summaryrefslogtreecommitdiff
path: root/python/src/com/jetbrains/python/console
diff options
context:
space:
mode:
authorTor Norbye <tnorbye@google.com>2014-08-19 12:53:10 -0700
committerTor Norbye <tnorbye@google.com>2014-08-19 12:53:10 -0700
commit02cf98d65c798d368fcec43ed64a001d513bdd4f (patch)
treee39e210ab20917b7e5ffdce14a42f5747506eed0 /python/src/com/jetbrains/python/console
parent2e5965e996aad62ab1338b09d54caaf99ff3dd6a (diff)
downloadidea-02cf98d65c798d368fcec43ed64a001d513bdd4f.tar.gz
Snapshot idea/138.1503 from git://git.jetbrains.org/idea/community.git
Change-Id: Ie01af1d8710ec0ff51d90301bda1a18b0b5c0faf
Diffstat (limited to 'python/src/com/jetbrains/python/console')
-rw-r--r--python/src/com/jetbrains/python/console/PydevConsoleRunner.java116
-rw-r--r--python/src/com/jetbrains/python/console/PythonConsoleToolWindow.java127
-rw-r--r--python/src/com/jetbrains/python/console/PythonConsoleToolWindowFactory.java33
-rw-r--r--python/src/com/jetbrains/python/console/RunPythonConsoleAction.java8
4 files changed, 264 insertions, 20 deletions
diff --git a/python/src/com/jetbrains/python/console/PydevConsoleRunner.java b/python/src/com/jetbrains/python/console/PydevConsoleRunner.java
index 3d77ac4f62b1..848818b95e27 100644
--- a/python/src/com/jetbrains/python/console/PydevConsoleRunner.java
+++ b/python/src/com/jetbrains/python/console/PydevConsoleRunner.java
@@ -16,6 +16,10 @@
package com.jetbrains.python.console;
import com.google.common.base.CharMatcher;
+import com.google.common.base.Function;
+import com.google.common.base.Predicate;
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.intellij.execution.ExecutionException;
import com.intellij.execution.ExecutionHelper;
@@ -59,11 +63,14 @@ import com.intellij.openapi.util.io.StreamUtil;
import com.intellij.openapi.vfs.CharsetToolkit;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.encoding.EncodingManager;
+import com.intellij.openapi.wm.ToolWindow;
+import com.intellij.openapi.wm.ToolWindowManager;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.impl.source.tree.FileElement;
import com.intellij.remote.RemoteSshProcess;
import com.intellij.testFramework.LightVirtualFile;
+import com.intellij.ui.content.Content;
import com.intellij.util.ArrayUtil;
import com.intellij.util.IJSwingUtilities;
import com.intellij.util.PathMappingSettings;
@@ -132,6 +139,9 @@ public class PydevConsoleRunner extends AbstractConsoleRunnerWithHistory<PythonC
private static final long APPROPRIATE_TO_WAIT = 60000;
private PyRemoteSdkCredentials myRemoteCredentials;
+ private ToolWindow myToolWindow;
+
+ private String myConsoleTitle = null;
protected PydevConsoleRunner(@NotNull final Project project,
@NotNull Sdk sdk, @NotNull final PyConsoleType consoleType,
@@ -192,8 +202,10 @@ public class PydevConsoleRunner extends AbstractConsoleRunnerWithHistory<PythonC
@NotNull final PyConsoleType consoleType,
@Nullable final String workingDirectory,
@NotNull final Map<String, String> environmentVariables,
+ @Nullable final ToolWindow toolWindow,
final String... statements2execute) {
final PydevConsoleRunner consoleRunner = create(project, sdk, consoleType, workingDirectory, environmentVariables);
+ consoleRunner.setToolWindow(toolWindow);
consoleRunner.setStatementsToExecute(statements2execute);
consoleRunner.run();
return consoleRunner;
@@ -481,6 +493,20 @@ public class PydevConsoleRunner extends AbstractConsoleRunnerWithHistory<PythonC
}
}
+ @Override
+ protected String constructConsoleTitle(@NotNull String consoleTitle) {
+ if (myConsoleTitle == null) {
+ myConsoleTitle = super.constructConsoleTitle(consoleTitle);
+ }
+ return myConsoleTitle;
+ }
+
+ @Override
+ protected void showConsole(Executor defaultExecutor, RunContentDescriptor contentDescriptor) {
+ PythonConsoleToolWindow terminalView = PythonConsoleToolWindow.getInstance(getProject());
+ terminalView.init(getToolWindow(), contentDescriptor);
+ }
+
protected AnAction createRerunAction() {
return new RestartAction(this);
}
@@ -583,9 +609,32 @@ public class PydevConsoleRunner extends AbstractConsoleRunnerWithHistory<PythonC
}
@Override
- protected AnAction createCloseAction(Executor defaultExecutor, RunContentDescriptor myDescriptor) {
- final AnAction generalCloseAction = super.createCloseAction(defaultExecutor, myDescriptor);
- return createConsoleStoppingAction(generalCloseAction);
+ protected AnAction createCloseAction(Executor defaultExecutor, final RunContentDescriptor descriptor) {
+ final AnAction generalCloseAction = super.createCloseAction(defaultExecutor, descriptor);
+
+ final AnAction stopAction = new DumbAwareAction() {
+ @Override
+ public void update(AnActionEvent e) {
+ generalCloseAction.update(e);
+ }
+
+ @Override
+ public void actionPerformed(AnActionEvent e) {
+ e = stopConsole(e);
+
+ clearContent(descriptor);
+
+ generalCloseAction.actionPerformed(e);
+ }
+ };
+ stopAction.copyFrom(generalCloseAction);
+ return stopAction;
+ }
+
+ private void clearContent(RunContentDescriptor descriptor) {
+ Content content = getToolWindow().getContentManager().findContent(descriptor.getDisplayName());
+ assert content != null;
+ getToolWindow().getContentManager().removeContent(content, true);
}
private AnAction createConsoleStoppingAction(final AnAction generalStopAction) {
@@ -597,26 +646,31 @@ public class PydevConsoleRunner extends AbstractConsoleRunnerWithHistory<PythonC
@Override
public void actionPerformed(AnActionEvent e) {
- if (myPydevConsoleCommunication != null) {
- final AnActionEvent furtherActionEvent =
- new AnActionEvent(e.getInputEvent(), e.getDataContext(), e.getPlace(),
- e.getPresentation(), e.getActionManager(), e.getModifiers());
- try {
- closeCommunication();
- // waiting for REPL communication before destroying process handler
- Thread.sleep(300);
- }
- catch (Exception ignored) {
- // Ignore
- }
- generalStopAction.actionPerformed(furtherActionEvent);
- }
+ e = stopConsole(e);
+
+ generalStopAction.actionPerformed(e);
}
};
stopAction.copyFrom(generalStopAction);
return stopAction;
}
+ private AnActionEvent stopConsole(AnActionEvent e) {
+ if (myPydevConsoleCommunication != null) {
+ e = new AnActionEvent(e.getInputEvent(), e.getDataContext(), e.getPlace(),
+ e.getPresentation(), e.getActionManager(), e.getModifiers());
+ try {
+ closeCommunication();
+ // waiting for REPL communication before destroying process handler
+ Thread.sleep(300);
+ }
+ catch (Exception ignored) {
+ // Ignore
+ }
+ }
+ return e;
+ }
+
protected AnAction createSplitLineAction() {
class ConsoleSplitLineAction extends EditorAction {
@@ -738,6 +792,17 @@ public class PydevConsoleRunner extends AbstractConsoleRunnerWithHistory<PythonC
}
}
+ public ToolWindow getToolWindow() {
+ if (myToolWindow == null) {
+ myToolWindow = ToolWindowManager.getInstance(getProject()).getToolWindow(PythonConsoleToolWindowFactory.ID);
+ }
+ return myToolWindow;
+ }
+
+ public void setToolWindow(ToolWindow toolWindow) {
+ myToolWindow = toolWindow;
+ }
+
public interface ConsoleListener {
void handleConsoleInitialized(LanguageConsoleView consoleView);
}
@@ -889,4 +954,21 @@ public class PydevConsoleRunner extends AbstractConsoleRunnerWithHistory<PythonC
return session;
}
+
+ @Override
+ protected List<String> getActiveConsoleNames(final String consoleTitle) {
+ return FluentIterable.from(
+ Lists.newArrayList(PythonConsoleToolWindow.getInstance(getProject()).getToolWindow().getContentManager().getContents())).transform(
+ new Function<Content, String>() {
+ @Override
+ public String apply(Content input) {
+ return input.getDisplayName();
+ }
+ }).filter(new Predicate<String>() {
+ @Override
+ public boolean apply(String input) {
+ return input.contains(consoleTitle);
+ }
+ }).toList();
+ }
}
diff --git a/python/src/com/jetbrains/python/console/PythonConsoleToolWindow.java b/python/src/com/jetbrains/python/console/PythonConsoleToolWindow.java
new file mode 100644
index 000000000000..e8c50e49280a
--- /dev/null
+++ b/python/src/com/jetbrains/python/console/PythonConsoleToolWindow.java
@@ -0,0 +1,127 @@
+package com.jetbrains.python.console;
+
+import com.intellij.execution.ui.RunContentDescriptor;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.SimpleToolWindowPanel;
+import com.intellij.openapi.wm.ToolWindow;
+import com.intellij.openapi.wm.ToolWindowManager;
+import com.intellij.openapi.wm.ex.ToolWindowManagerEx;
+import com.intellij.openapi.wm.ex.ToolWindowManagerListener;
+import com.intellij.openapi.wm.impl.content.ToolWindowContentUi;
+import com.intellij.ui.content.Content;
+import com.intellij.ui.content.ContentFactory;
+import org.jetbrains.annotations.NotNull;
+
+import javax.swing.*;
+import java.awt.event.FocusEvent;
+import java.awt.event.FocusListener;
+
+/**
+ * @author traff
+ */
+public class PythonConsoleToolWindow {
+
+ private final Project myProject;
+
+ private boolean myInitialized = false;
+
+ public PythonConsoleToolWindow(Project project) {
+ myProject = project;
+ }
+
+ public static PythonConsoleToolWindow getInstance(@NotNull Project project) {
+ return project.getComponent(PythonConsoleToolWindow.class);
+ }
+
+
+ public void init(final @NotNull ToolWindow toolWindow, final @NotNull RunContentDescriptor contentDescriptor) {
+ addContent(toolWindow, contentDescriptor);
+
+ if (!myInitialized) {
+ doInit(toolWindow);
+ }
+ }
+
+ private void doInit(final ToolWindow toolWindow) {
+ myInitialized = true;
+
+ toolWindow.setToHideOnEmptyContent(true);
+
+ ((ToolWindowManagerEx)ToolWindowManager.getInstance(myProject)).addToolWindowManagerListener(new ToolWindowManagerListener() {
+ @Override
+ public void toolWindowRegistered(@NotNull String id) {
+ }
+
+ @Override
+ public void stateChanged() {
+ ToolWindow window = getToolWindow();
+ if (window != null) {
+ boolean visible = window.isVisible();
+ if (visible && toolWindow.getContentManager().getContentCount() == 0) {
+ RunPythonConsoleAction.runPythonConsole(myProject, null, toolWindow);
+ }
+ }
+ }
+ });
+ }
+
+ private static void addContent(ToolWindow toolWindow, RunContentDescriptor contentDescriptor) {
+ toolWindow.getComponent().putClientProperty(ToolWindowContentUi.HIDE_ID_LABEL, "true");
+
+ Content content = toolWindow.getContentManager().findContent(contentDescriptor.getDisplayName());
+ if (content == null) {
+ content = createContent(contentDescriptor);
+ toolWindow.getContentManager().addContent(content);
+ }
+ else {
+ SimpleToolWindowPanel panel = new SimpleToolWindowPanel(false, true);
+ resetContent(contentDescriptor, panel, content);
+ }
+
+ toolWindow.getContentManager().setSelectedContent(content);
+ }
+
+ public ToolWindow getToolWindow() {
+ return ToolWindowManager.getInstance(myProject).getToolWindow(PythonConsoleToolWindowFactory.ID);
+ }
+
+ private static Content createContent(final @NotNull RunContentDescriptor contentDescriptor) {
+ SimpleToolWindowPanel panel = new SimpleToolWindowPanel(false, true);
+
+ final Content content = ContentFactory.SERVICE.getInstance().createContent(panel, contentDescriptor.getDisplayName(), false);
+ content.setCloseable(true);
+
+ resetContent(contentDescriptor, panel, content);
+
+ return content;
+ }
+
+ private static void resetContent(RunContentDescriptor contentDescriptor, SimpleToolWindowPanel panel, Content content) {
+ panel.setContent(contentDescriptor.getComponent());
+ //panel.addFocusListener(createFocusListener(toolWindow));
+
+ content.setComponent(panel);
+ content.setPreferredFocusableComponent(contentDescriptor.getComponent());
+ }
+
+ private static FocusListener createFocusListener(final ToolWindow toolWindow) {
+ return new FocusListener() {
+ @Override
+ public void focusGained(FocusEvent e) {
+ JComponent component = getComponentToFocus(toolWindow);
+ if (component != null) {
+ component.requestFocusInWindow();
+ }
+ }
+
+ @Override
+ public void focusLost(FocusEvent e) {
+
+ }
+ };
+ }
+
+ private static JComponent getComponentToFocus(ToolWindow window) {
+ return window.getContentManager().getComponent();
+ }
+}
diff --git a/python/src/com/jetbrains/python/console/PythonConsoleToolWindowFactory.java b/python/src/com/jetbrains/python/console/PythonConsoleToolWindowFactory.java
new file mode 100644
index 000000000000..f042a539bc22
--- /dev/null
+++ b/python/src/com/jetbrains/python/console/PythonConsoleToolWindowFactory.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2000-2014 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.python.console;
+
+import com.intellij.openapi.project.DumbAware;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.wm.ToolWindow;
+import com.intellij.openapi.wm.ToolWindowFactory;
+
+/**
+ * @author traff
+ */
+public class PythonConsoleToolWindowFactory implements ToolWindowFactory, DumbAware {
+ public static final String ID = "Python Console";
+
+ @Override
+ public void createToolWindowContent(Project project, ToolWindow toolWindow) {
+ RunPythonConsoleAction.runPythonConsole(project, null, toolWindow);
+ }
+}
diff --git a/python/src/com/jetbrains/python/console/RunPythonConsoleAction.java b/python/src/com/jetbrains/python/console/RunPythonConsoleAction.java
index 02a153f7a016..566adea43c87 100644
--- a/python/src/com/jetbrains/python/console/RunPythonConsoleAction.java
+++ b/python/src/com/jetbrains/python/console/RunPythonConsoleAction.java
@@ -32,6 +32,7 @@ import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.openapi.wm.ToolWindow;
import com.intellij.util.PathMappingSettings;
import com.jetbrains.python.buildout.BuildoutFacet;
import com.jetbrains.python.remote.PyRemoteSdkAdditionalDataBase;
@@ -42,6 +43,7 @@ import com.jetbrains.python.sdk.PythonEnvUtil;
import com.jetbrains.python.sdk.PythonSdkType;
import icons.PythonIcons;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import java.util.Collection;
import java.util.List;
@@ -77,11 +79,11 @@ public class RunPythonConsoleAction extends AnAction implements DumbAware {
public void actionPerformed(final AnActionEvent e) {
final Project project = e.getData(CommonDataKeys.PROJECT);
- runPythonConsole(project, e.getData(LangDataKeys.MODULE));
+ runPythonConsole(project, e.getData(LangDataKeys.MODULE), null);
}
@NotNull
- public static PydevConsoleRunner runPythonConsole(Project project, Module contextModule) {
+ public static PydevConsoleRunner runPythonConsole(Project project, Module contextModule, @Nullable ToolWindow toolWindow) {
assert project != null : "Project is null";
Pair<Sdk, Module> sdkAndModule = findPythonSdkAndModule(project, contextModule);
@@ -152,7 +154,7 @@ public class RunPythonConsoleAction extends AnAction implements DumbAware {
envs.put(PythonEnvUtil.IPYTHONENABLE, ipythonEnabled);
return PydevConsoleRunner
- .createAndRun(project, sdk, PyConsoleType.PYTHON, workingDir, envs, setupFragment);
+ .createAndRun(project, sdk, PyConsoleType.PYTHON, workingDir, envs, toolWindow, setupFragment);
}
public static PathMappingSettings getMappings(Project project, Sdk sdk) {