replaced watches tab with simplified console
authorliana.bakradze <liana.bakradze@jetbrains.com>
Thu, 30 Jul 2015 09:38:30 +0000 (12:38 +0300)
committerliana.bakradze <liana.bakradze@jetbrains.com>
Thu, 30 Jul 2015 12:37:49 +0000 (15:37 +0300)
python/edu/src/META-INF/PyCharmEduPlugin.xml
python/edu/src/com/jetbrains/python/edu/debugger/PyEduConsoleOutputFilter.java [new file with mode: 0644]
python/edu/src/com/jetbrains/python/edu/debugger/PyEduDebugRunner.java
python/educational/course-creator/src/com/jetbrains/edu/coursecreator/actions/CCRunTestsAction.java
python/src/META-INF/python-core.xml
python/src/com/jetbrains/python/console/PyConsoleOutputFilter.java [new file with mode: 0644]
python/src/com/jetbrains/python/console/PythonConsoleView.java
python/src/com/jetbrains/python/debugger/PyDebugRunner.java

index b676ee5fd53c79d9c1e8046be2bda9f5aa2dbe23..da680fc346baf397218de8800bbe7a34cff82f10 100644 (file)
@@ -37,6 +37,7 @@
   <extensions defaultExtensionNs="Pythonid">
     <pyDebugValueTransformer implementation="com.jetbrains.python.edu.debugger.PyEduDebugTransformer"/>
     <pyFramesTransformer implementation="com.jetbrains.python.edu.debugger.PyEduFramesTransformer"/>
+    <pyConsoleOutputFilter implementation="com.jetbrains.python.edu.debugger.PyEduConsoleOutputFilter"/>
   </extensions>
 
   <actions>
diff --git a/python/edu/src/com/jetbrains/python/edu/debugger/PyEduConsoleOutputFilter.java b/python/edu/src/com/jetbrains/python/edu/debugger/PyEduConsoleOutputFilter.java
new file mode 100644 (file)
index 0000000..d1bde91
--- /dev/null
@@ -0,0 +1,18 @@
+package com.jetbrains.python.edu.debugger;
+
+import com.intellij.execution.ui.ConsoleViewContentType;
+import com.jetbrains.python.console.PyConsoleOutputFilter;
+import org.jetbrains.annotations.NotNull;
+
+public class PyEduConsoleOutputFilter implements PyConsoleOutputFilter {
+  @Override
+  public boolean reject(@NotNull String text, @NotNull ConsoleViewContentType outputType) {
+    if (outputType.equals(ConsoleViewContentType.SYSTEM_OUTPUT) && !text.contains("exit code")) {
+      return true;
+    }
+    if (text.startsWith("pydev debugger")) {
+      return true;
+    }
+    return false;
+  }
+}
index 3e358292c309736f3adb08194a85331632b3ea06..98071490addb0ca71135534c8b8704621d093258 100644 (file)
@@ -2,23 +2,42 @@ package com.jetbrains.python.edu.debugger;
 
 import com.intellij.codeInsight.daemon.impl.CollectHighlightsUtil;
 import com.intellij.execution.ExecutionResult;
+import com.intellij.execution.Executor;
 import com.intellij.execution.configurations.RunProfile;
+import com.intellij.execution.configurations.RunProfileState;
+import com.intellij.execution.filters.UrlFilter;
 import com.intellij.execution.process.ProcessHandler;
 import com.intellij.execution.ui.ExecutionConsole;
+import com.intellij.execution.ui.RunnerLayoutUi;
+import com.intellij.execution.ui.layout.PlaceInGrid;
+import com.intellij.icons.AllIcons;
+import com.intellij.ide.DataManager;
+import com.intellij.openapi.actionSystem.ActionPlaces;
+import com.intellij.openapi.actionSystem.AnAction;
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.actionSystem.Presentation;
 import com.intellij.openapi.editor.Document;
 import com.intellij.openapi.fileEditor.FileDocumentManager;
+import com.intellij.openapi.module.ModuleManager;
 import com.intellij.openapi.project.Project;
+import com.intellij.openapi.projectRoots.Sdk;
 import com.intellij.openapi.vfs.VfsUtil;
 import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.psi.*;
+import com.intellij.ui.content.Content;
+import com.intellij.ui.content.ContentManager;
 import com.intellij.util.containers.Predicate;
 import com.intellij.xdebugger.XDebugSession;
 import com.intellij.xdebugger.XDebuggerManager;
 import com.intellij.xdebugger.breakpoints.XBreakpointManager;
 import com.intellij.xdebugger.breakpoints.XBreakpointProperties;
+import com.intellij.xdebugger.impl.XDebugSessionImpl;
 import com.intellij.xdebugger.impl.breakpoints.LineBreakpointState;
 import com.intellij.xdebugger.impl.breakpoints.XBreakpointManagerImpl;
 import com.intellij.xdebugger.impl.breakpoints.XLineBreakpointImpl;
+import com.intellij.xdebugger.impl.ui.XDebugSessionTab;
+import com.jetbrains.python.PyBundle;
+import com.jetbrains.python.console.PythonDebugLanguageConsoleView;
 import com.jetbrains.python.debugger.*;
 import com.jetbrains.python.documentation.DocStringUtil;
 import com.jetbrains.python.edu.PyEduUtils;
@@ -26,6 +45,8 @@ import com.jetbrains.python.psi.PyExpression;
 import com.jetbrains.python.psi.PyExpressionStatement;
 import com.jetbrains.python.psi.PyImportStatement;
 import com.jetbrains.python.run.PythonCommandLineState;
+import com.jetbrains.python.run.PythonTracebackFilter;
+import com.jetbrains.python.sdk.PythonSdkType;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
@@ -44,6 +65,7 @@ public class PyEduDebugRunner extends PyDebugRunner {
              (isDocString(input));
     }
   };
+  public static final String OUTPUT = "Output";
 
   @Override
   public boolean canRun(@NotNull String executorId, @NotNull RunProfile profile) {
@@ -92,6 +114,72 @@ public class PyEduDebugRunner extends PyDebugRunner {
     }
   }
 
+
+  @Override
+  protected void initSession(XDebugSession session, RunProfileState state, Executor executor) {
+    XDebugSessionTab tab = ((XDebugSessionImpl)session).getSessionTab();
+    if (tab != null) {
+      RunnerLayoutUi ui = tab.getUi();
+      ContentManager contentManager = ui.getContentManager();
+      Content content = findContent(contentManager, "Watches");
+      if (content != null) {
+        contentManager.removeContent(content, true);
+      }
+      content = findContent(contentManager, "Console");
+      if (content != null) {
+        contentManager.removeContent(content, true);
+      }
+      initEduConsole(session, ui);
+    }
+  }
+
+  private static void initEduConsole(@NotNull final XDebugSession session,
+                                     @NotNull final RunnerLayoutUi ui) {
+    Project project = session.getProject();
+    final Sdk sdk = PythonSdkType.findPythonSdk(ModuleManager.getInstance(project).getModules()[0]);
+    final PythonDebugLanguageConsoleView view = new PythonDebugLanguageConsoleView(project, sdk);
+    final ProcessHandler processHandler = session.getDebugProcess().getProcessHandler();
+
+    view.attachToProcess(processHandler);
+    view.addMessageFilter(new PythonTracebackFilter(project));
+    view.addMessageFilter(new UrlFilter());
+
+    switchToPythonConsole(view);
+
+    Content eduConsole =
+      ui.createContent(OUTPUT, view.getComponent() , OUTPUT, AllIcons.Debugger.ToolConsole, view.getPreferredFocusableComponent());
+    eduConsole.setCloseable(false);
+    ui.addContent(eduConsole, 0, PlaceInGrid.right, false);
+
+    PyDebugProcess process = (PyDebugProcess)session.getDebugProcess();
+    PyDebugRunner.initDebugConsoleView(project, process, view, processHandler, session);
+  }
+
+  private static void switchToPythonConsole(PythonDebugLanguageConsoleView view) {
+    AnAction[] actions = view.createConsoleActions();
+    for (AnAction action : actions) {
+      Presentation presentation = action.getTemplatePresentation();
+      String text = presentation.getText();
+      if (PyBundle.message("run.configuration.show.command.line.action.name").equals(text)) {
+        AnActionEvent event =
+          AnActionEvent.createFromAnAction(action, null,
+                                           ActionPlaces.DEBUGGER_TOOLBAR, DataManager.getInstance().getDataContext(view));
+        action.actionPerformed(event);
+      }
+    }
+  }
+
+  @Nullable
+  private static Content findContent(ContentManager manager, String name) {
+    for (Content content : manager.getContents()) {
+      if (content.getDisplayName().equals(name)) {
+        return content;
+      }
+    }
+    return null;
+  }
+
+
   private static boolean isDocString(PsiElement element) {
     if (element instanceof PyExpressionStatement) {
       element = ((PyExpressionStatement)element).getExpression();
@@ -102,7 +190,7 @@ public class PyEduDebugRunner extends PyDebugRunner {
     return false;
   }
 
-  private class PyEduDebugProcess extends PyDebugProcess {
+  private static class PyEduDebugProcess extends PyDebugProcess {
     public PyEduDebugProcess(@NotNull XDebugSession session,
                              @NotNull ServerSocket serverSocket,
                              @NotNull ExecutionConsole executionConsole,
index f1d9d6cba0631ad5ad07bdc70a0ef582226a4c93..851475b8afe025a4e82b43576d3dd9ce35ed80c4 100644 (file)
@@ -56,6 +56,11 @@ public abstract class CCRunTestsAction extends AnAction {
 
   @Override
   public void update(@NotNull AnActionEvent e) {
+    if (!CCProjectService.setCCActionAvailable(e)) {
+      EduUtils.enableAction(e, false);
+      return;
+    }
+
     Presentation presentation = e.getPresentation();
     presentation.setText("");
     presentation.setVisible(false);
index aa537166a6626b883ae5f4b178b893ba2ae7e0fe..e77452a9d3e7835dc16019bbf325c3e3e001b565 100644 (file)
     <extensionPoint qualifiedName="Pythonid.pyRootTypeProvider" interface="com.jetbrains.python.module.PyRootTypeProvider"/>
     <extensionPoint qualifiedName="Pythonid.pyDebugValueTransformer" interface="com.jetbrains.python.debugger.PyDebugValueTransformer"/>
     <extensionPoint qualifiedName="Pythonid.pyFramesTransformer" interface="com.jetbrains.python.debugger.PyFramesTransformer"/>
+    <extensionPoint qualifiedName="Pythonid.pyConsoleOutputFilter" interface="com.jetbrains.python.console.PyConsoleOutputFilter"/>
   </extensionPoints>
 
   <extensions defaultExtensionNs="Pythonid">
diff --git a/python/src/com/jetbrains/python/console/PyConsoleOutputFilter.java b/python/src/com/jetbrains/python/console/PyConsoleOutputFilter.java
new file mode 100644 (file)
index 0000000..4575943
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * 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.python.console;
+
+import com.intellij.execution.ui.ConsoleViewContentType;
+import com.intellij.openapi.extensions.ExtensionPointName;
+import org.jetbrains.annotations.NotNull;
+
+public interface PyConsoleOutputFilter {
+  ExtensionPointName<PyConsoleOutputFilter> EP_NAME = ExtensionPointName.create("Pythonid.pyConsoleOutputFilter");
+
+  boolean reject(@NotNull String text, @NotNull final ConsoleViewContentType outputType);
+}
index d5ddcb6f5175b044c264b7a32985e8622c91b685..a78fc2e61401738c3fd2298510556b975cc256bb 100644 (file)
@@ -25,6 +25,7 @@ import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.editor.Editor;
 import com.intellij.openapi.editor.colors.EditorColorsScheme;
+import com.intellij.openapi.extensions.Extensions;
 import com.intellij.openapi.progress.ProgressIndicator;
 import com.intellij.openapi.progress.ProgressManager;
 import com.intellij.openapi.progress.Task;
@@ -177,6 +178,12 @@ public class PythonConsoleView extends LanguageConsoleImpl implements Observable
 
   @Override
   public void print(@NotNull String text, @NotNull final ConsoleViewContentType outputType) {
+    for (PyConsoleOutputFilter filter : Extensions.getExtensions(PyConsoleOutputFilter.EP_NAME)) {
+      if (filter.reject(text, outputType)) {
+        return;
+      }
+    }
+
     detectIPython(text, outputType);
     if (PyConsoleUtil.detectIPythonEnd(text)) {
       myIsIPythonOutput = false;
index 2c1454ca285af9b450d43813ef190abab3cb5628..2d0c5416350fd7852f53cfae428c74094c8851ae 100644 (file)
@@ -18,6 +18,7 @@ package com.jetbrains.python.debugger;
 import com.google.common.collect.Lists;
 import com.intellij.execution.ExecutionException;
 import com.intellij.execution.ExecutionResult;
+import com.intellij.execution.Executor;
 import com.intellij.execution.configurations.*;
 import com.intellij.execution.console.LanguageConsoleBuilder;
 import com.intellij.execution.executors.DefaultDebugExecutor;
@@ -121,7 +122,12 @@ public class PyDebugRunner extends GenericProgramRunner {
 
   @Override
   protected RunContentDescriptor doExecute(@NotNull RunProfileState state, @NotNull final ExecutionEnvironment environment) throws ExecutionException {
-    return createSession(state, environment).getRunContentDescriptor();
+    XDebugSession session = createSession(state, environment);
+    initSession(session, state, environment.getExecutor());
+    return session.getRunContentDescriptor();
+  }
+
+  protected void initSession(XDebugSession session, RunProfileState state, Executor executor) {
   }
 
   public static int findIndex(List<String> paramList, String paramName) {