diff --git a/python/src/META-INF/python-core-common.xml b/python/src/META-INF/python-core-common.xml
index 02d049504778..7c7d27da28ff 100644
--- a/python/src/META-INF/python-core-common.xml
+++ b/python/src/META-INF/python-core-common.xml
@@ -46,7 +46,7 @@
-
+
@@ -624,16 +624,14 @@
-
-
-
+
@@ -881,10 +879,6 @@
-
-
-
-
@@ -892,17 +886,6 @@
-
-
- com.jetbrains.python.actions.PySciProjectComponent
-
-
-
-
- com.jetbrains.python.plots.PyPlotToolWindow
-
-
-
com.jetbrains.python.testing.VFSTestFrameworkListener
diff --git a/python/src/com/jetbrains/python/actions/PySciProjectComponent.java b/python/src/com/jetbrains/python/actions/PySciProjectComponent.java
deleted file mode 100644
index 6ce5c5cd3ff5..000000000000
--- a/python/src/com/jetbrains/python/actions/PySciProjectComponent.java
+++ /dev/null
@@ -1,235 +0,0 @@
-/*
- * 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.jetbrains.python.actions;
-
-import com.intellij.codeInsight.documentation.DocumentationManager;
-import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.components.AbstractProjectComponent;
-import com.intellij.openapi.components.PersistentStateComponent;
-import com.intellij.openapi.components.State;
-import com.intellij.openapi.components.Storage;
-import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.editor.colors.EditorColorsManager;
-import com.intellij.openapi.editor.colors.EditorColorsScheme;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.startup.StartupManager;
-import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.openapi.wm.ToolWindow;
-import com.intellij.openapi.wm.ToolWindowManager;
-import com.intellij.psi.PsiDirectory;
-import com.intellij.psi.PsiManager;
-import com.intellij.ui.content.Content;
-import com.intellij.util.ui.UIUtil;
-import com.jetbrains.python.plots.PyPlotToolWindow;
-import org.jetbrains.annotations.Nullable;
-
-import java.io.DataInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.ServerSocket;
-import java.net.Socket;
-
-import static com.intellij.codeInsight.documentation.DocumentationComponent.COLOR_KEY;
-import static com.jetbrains.python.actions.PySciViewAction.hideDataViewer;
-import static com.jetbrains.python.actions.PySciViewAction.showDataViewAsToolwindow;
-import static com.jetbrains.python.debugger.containerview.PyDataView.DATA_VIEWER_ID;
-
-@State(name = "PySciProjectComponent", storages = @Storage("other.xml"))
-public class PySciProjectComponent extends AbstractProjectComponent implements PersistentStateComponent {
- private State myState = new State();
- private ServerSocket myServerSocket;
- private Thread myPlotsThread;
- private volatile boolean myShouldAccept = true;
-
- private static final Logger LOG = Logger.getInstance(PySciProjectComponent.class);
-
- protected PySciProjectComponent(Project project) {
- super(project);
- }
-
- public static PySciProjectComponent getInstance(Project project) {
- return project.getComponent(PySciProjectComponent.class);
- }
-
- public void useSciView(boolean useSciView) {
- myState.PY_SCI_VIEW = useSciView;
- }
-
- public void sciViewSuggested(boolean suggested) {
- myState.PY_SCI_VIEW_SUGGESTED = suggested;
- }
-
- public boolean sciViewSuggested() {
- return myState.PY_SCI_VIEW_SUGGESTED;
- }
-
- public boolean useSciView() {
- return myState.PY_SCI_VIEW;
- }
-
- public void matplotlibInToolwindow(boolean inToolwindow) {
- myState.PY_MATPLOTLIB_IN_TOOLWINDOW = inToolwindow;
-
- if (inToolwindow) {
- if (myServerSocket == null) {
- initializeServerSocket();
- }
- if (!useSciView()) {
- showDataViewAsToolwindow(myProject);
- }
- }
- else if (!useSciView()) {
- hideDataViewer(myProject);
- }
- }
-
- public boolean matplotlibInToolwindow() {
- return myState.PY_MATPLOTLIB_IN_TOOLWINDOW;
- }
-
- @Override
- public void projectOpened() {
- final VirtualFile baseDir = myProject.getBaseDir();
- if (baseDir == null) return;
- if (ApplicationManager.getApplication().isUnitTestMode()) return;
- if (myState.PY_SCI_VIEW) {
- StartupManager.getInstance(myProject).runWhenProjectIsInitialized(() -> {
- EditorColorsScheme scheme = EditorColorsManager.getInstance().getGlobalScheme();
- scheme.setColor(COLOR_KEY, UIUtil.getEditorPaneBackground());
-
- final PsiDirectory directory = PsiManager.getInstance(myProject).findDirectory(baseDir);
- if (directory != null) {
- DocumentationManager.getInstance(myProject).showJavaDocInfo(directory, directory);
- }
- });
- }
- if (matplotlibInToolwindow()) {
- initializeServerSocket();
-
- if (!useSciView()) {
- StartupManager.getInstance(myProject).runWhenProjectIsInitialized(() -> showDataViewAsToolwindow(myProject));
- }
- }
- }
-
- private void initializeServerSocket() {
- try {
- myServerSocket = new ServerSocket(0);
- }
- catch (IOException e) {
- LOG.error("Failed to initialize server socket for python plots " + e.getMessage());
- return;
- }
- myPlotsThread = new Thread(()->{
- while (myShouldAccept) {
- processConnection();
- }
- }, "Python plots client");
- myPlotsThread.setDaemon(true);
- myPlotsThread.start();
- }
-
- private void processConnection() {
- try {
- final Socket socket = myServerSocket.accept();
- try {
- final InputStream stream = socket.getInputStream();
- final DataInputStream inputStream = new DataInputStream(stream);
- try {
- final int width = inputStream.readInt();
- final int count = inputStream.readInt();
- final byte[] raw = new byte[count];
- inputStream.readFully(raw);
-
- PyPlotToolWindow.getInstance(myProject).onMessage(width, raw);
- ToolWindow window = ToolWindowManager.getInstance(myProject).getToolWindow(DATA_VIEWER_ID);
- if (window == null) {
- return;
- }
- ApplicationManager.getApplication().invokeLater(() -> {
- window.show(null);
- final Content plotsTab = window.getContentManager().getContent(1);
- if (plotsTab != null) {
- window.getContentManager().setSelectedContent(plotsTab);
- }
- });
- }
- catch (IOException e) {
- LOG.error(e.getMessage());
- }
- finally {
- inputStream.close();
- }
- }
- finally {
- if (!socket.isClosed()) {
- socket.close();
- }
- }
- }
- catch (IOException e) {
- if (myServerSocket == null) {
- myShouldAccept = false;
- }
- }
- }
-
- public void stopMatplotlibCommunication() {
- if (myServerSocket != null && !myServerSocket.isClosed()) {
- try {
- myServerSocket.close();
- } catch (IOException ignore) {
- }
- }
- myShouldAccept = false;
- myServerSocket = null;
- try {
- if (myPlotsThread != null) {
- myPlotsThread.join();
- }
- }
- catch (InterruptedException ignored) {
- }
- }
-
- public int getPort() {
- return myServerSocket != null ? myServerSocket.getLocalPort() : -1;
- }
-
- @Override
- public void projectClosed() {
- stopMatplotlibCommunication();
- }
-
- @Nullable
- @Override
- public PySciProjectComponent.State getState() {
- return myState;
- }
-
- @Override
- public void loadState(PySciProjectComponent.State state) {
- myState.PY_SCI_VIEW = state.PY_SCI_VIEW;
- myState.PY_SCI_VIEW_SUGGESTED = state.PY_SCI_VIEW_SUGGESTED;
- myState.PY_MATPLOTLIB_IN_TOOLWINDOW = state.PY_MATPLOTLIB_IN_TOOLWINDOW;
- }
-
- public static class State {
- public boolean PY_SCI_VIEW = false;
- public boolean PY_SCI_VIEW_SUGGESTED = false;
- public boolean PY_MATPLOTLIB_IN_TOOLWINDOW = true;
- }
-}
diff --git a/python/src/com/jetbrains/python/actions/PySciViewAction.java b/python/src/com/jetbrains/python/actions/PySciViewAction.java
deleted file mode 100644
index 3b4aa122b865..000000000000
--- a/python/src/com/jetbrains/python/actions/PySciViewAction.java
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- * 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.jetbrains.python.actions;
-
-import com.intellij.codeInsight.documentation.DocumentationManager;
-import com.intellij.execution.RunManager;
-import com.intellij.execution.RunnerAndConfigurationSettings;
-import com.intellij.execution.configurations.RunConfiguration;
-import com.intellij.ide.util.PropertiesComponent;
-import com.intellij.openapi.actionSystem.AnActionEvent;
-import com.intellij.openapi.actionSystem.CommonDataKeys;
-import com.intellij.openapi.actionSystem.Presentation;
-import com.intellij.openapi.actionSystem.ToggleAction;
-import com.intellij.openapi.editor.colors.EditorColorsManager;
-import com.intellij.openapi.editor.colors.EditorColorsScheme;
-import com.intellij.openapi.module.Module;
-import com.intellij.openapi.module.ModuleUtilCore;
-import com.intellij.openapi.options.FontSize;
-import com.intellij.openapi.project.DumbAware;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.ui.popup.JBPopup;
-import com.intellij.openapi.wm.ToolWindow;
-import com.intellij.openapi.wm.ToolWindowId;
-import com.intellij.openapi.wm.ToolWindowManager;
-import com.intellij.openapi.wm.ToolWindowType;
-import com.intellij.psi.PsiElement;
-import com.intellij.psi.PsiManager;
-import com.intellij.util.ui.UIUtil;
-import com.jetbrains.python.console.PythonConsoleToolWindow;
-import com.jetbrains.python.documentation.PyDocumentationSettings;
-import com.jetbrains.python.run.PythonConfigurationType;
-import com.jetbrains.python.run.PythonRunConfiguration;
-import org.jetbrains.annotations.NotNull;
-
-import java.awt.*;
-
-import static com.intellij.codeInsight.documentation.DocumentationComponent.COLOR_KEY;
-import static com.intellij.codeInsight.documentation.DocumentationComponent.QUICK_DOC_FONT_SIZE_PROPERTY;
-import static com.jetbrains.python.debugger.containerview.PyDataView.DATA_VIEWER_ID;
-
-public class PySciViewAction extends ToggleAction implements DumbAware {
- private static final String TEXT_SCI_VIEW = "Scientific Mode";
-
- private boolean wasConsoleVisible = false;
-
- public static final String ACTION_ID = "PySciView";
- private Color myDocumentationBackgroundColor = EditorColorsManager.getInstance().getGlobalScheme().getColor(COLOR_KEY);
-
- public PySciViewAction() {
- super(TEXT_SCI_VIEW);
- }
-
- @Override
- public boolean isSelected(AnActionEvent e) {
- return e.getProject() != null && PySciProjectComponent.getInstance(e.getProject()).useSciView();
- }
-
- @Override
- public void setSelected(AnActionEvent e, boolean state) {
- final Project project = e.getProject();
- if (project == null) return;
- PySciProjectComponent.getInstance(project).useSciView(state);
-
- final PsiElement element = getPsiElement(e, project);
-
- if (state) {
- showConsoleToolwindow(project);
- showDocumentationToolwindow(project, element);
- showDataViewAsToolwindow(project);
- showCommandLineInRunConfiguration(project, true);
- renderExternalDocumentation(element, true);
- }
- else {
- hideConsoleToolwindow(project);
- restoreDocumentationPopup(project);
- hideDataViewer(project);
- showCommandLineInRunConfiguration(project, false);
- renderExternalDocumentation(element, false);
- }
- }
-
- private static void renderExternalDocumentation(PsiElement element, boolean render) {
- final Module module = ModuleUtilCore.findModuleForPsiElement(element);
- if (module != null) {
- PyDocumentationSettings.getInstance(module).setRenderExternalDocumentation(render);
- }
- }
-
- private static void showCommandLineInRunConfiguration(Project project, boolean show) {
- final RunnerAndConfigurationSettings template =
- RunManager.getInstance(project).getConfigurationTemplate(PythonConfigurationType.getInstance().getFactory());
- final RunConfiguration configuration = template.getConfiguration();
- if (configuration instanceof PythonRunConfiguration) {
- ((PythonRunConfiguration)configuration).setShowCommandLineAfterwards(show);
- }
- }
-
- private void showConsoleToolwindow(@NotNull final Project project) {
- final PythonConsoleToolWindow pythonConsoleToolWindow = PythonConsoleToolWindow.getInstance(project);
- if (pythonConsoleToolWindow == null) return;
- final ToolWindow consoleToolWindow = pythonConsoleToolWindow.getToolWindow();
- if (consoleToolWindow == null) return;
- wasConsoleVisible = consoleToolWindow.isVisible();
- consoleToolWindow.show(null);
- }
-
- private void hideConsoleToolwindow(@NotNull final Project project) {
- if (!wasConsoleVisible) {
- final PythonConsoleToolWindow pythonConsoleToolWindow = PythonConsoleToolWindow.getInstance(project);
- if (pythonConsoleToolWindow != null) {
- final ToolWindow consoleToolWindow = pythonConsoleToolWindow.getToolWindow();
- if (consoleToolWindow != null) {
- consoleToolWindow.hide(null);
- }
- }
- }
- }
-
- private void showDocumentationToolwindow(Project project, PsiElement element) {
- final String showInToolWindowProperty = DocumentationManager.getInstance(project).getShowInToolWindowProperty();
-
- EditorColorsScheme scheme = EditorColorsManager.getInstance().getGlobalScheme();
- myDocumentationBackgroundColor = scheme.getColor(COLOR_KEY);
- scheme.setColor(COLOR_KEY, UIUtil.getEditorPaneBackground());
-
- PropertiesComponent.getInstance().setValue(showInToolWindowProperty, true);
- PropertiesComponent.getInstance().setValue(DocumentationManager.getInstance(project).getAutoUpdateEnabledProperty(), true);
-
- if (element != null) {
- DocumentationManager.getInstance(project).showJavaDocInfo(element, element);
- }
- setDocFontSize();
- }
-
- private static void setDocFontSize() {
- EditorColorsScheme scheme = EditorColorsManager.getInstance().getGlobalScheme();
- final int editorFontSize = scheme.getEditorFontSize();
- final FontSize[] values = FontSize.values();
- FontSize fontSize = FontSize.MEDIUM;
- for (FontSize value : values) {
- if (value.getSize() > editorFontSize) {
- break;
- }
- fontSize = value;
- }
-
- PropertiesComponent.getInstance().setValue(QUICK_DOC_FONT_SIZE_PROPERTY, String.valueOf(fontSize.toString()));
- }
-
- private void restoreDocumentationPopup(Project project) {
- PropertiesComponent.getInstance().setValue(DocumentationManager.getInstance(project).getAutoUpdateEnabledProperty(), false);
- EditorColorsScheme scheme = EditorColorsManager.getInstance().getGlobalScheme();
- scheme.setColor(COLOR_KEY, myDocumentationBackgroundColor);
-
- final ToolWindow window = ToolWindowManager.getInstance(project).getToolWindow(ToolWindowId.DOCUMENTATION);
- if (window != null) {
- DocumentationManager.getInstance(project).restorePopupBehavior();
- final JBPopup hint = DocumentationManager.getInstance(project).getDocInfoHint();
- if (hint != null) {
- hint.cancel();
- }
- }
- }
-
- public static void showDataViewAsToolwindow(@NotNull final Project project) {
- ToolWindow dataViewToolWindow = ToolWindowManager.getInstance(project).getToolWindow(DATA_VIEWER_ID);
- if (dataViewToolWindow != null) {
- dataViewToolWindow.setType(ToolWindowType.DOCKED, null);
- dataViewToolWindow.setAutoHide(false);
- dataViewToolWindow.setShowStripeButton(true);
- }
- }
-
- public static void hideDataViewer(Project project) {
- final ToolWindow dataViewer = ToolWindowManager.getInstance(project).getToolWindow(DATA_VIEWER_ID);
- if (dataViewer != null) {
- dataViewer.setType(ToolWindowType.FLOATING, null);
- dataViewer.setAutoHide(true);
- dataViewer.setShowStripeButton(false);
- }
- }
-
- private static PsiElement getPsiElement(AnActionEvent e, Project project) {
- PsiElement element = CommonDataKeys.PSI_ELEMENT.getData(e.getDataContext());
- if (element == null) {
- element = CommonDataKeys.PSI_FILE.getData(e.getDataContext());
- }
- if (element == null) {
- element = PsiManager.getInstance(project).findDirectory(project.getBaseDir());
- }
- return element;
- }
-
- @Override
- public void update(@NotNull AnActionEvent e) {
- super.update(e);
- final Project project = e.getProject();
- final Presentation presentation = e.getPresentation();
- presentation.setEnabledAndVisible(project != null);
- }
-}
diff --git a/python/src/com/jetbrains/python/configuration/PyIntegratedToolsConfigurable.form b/python/src/com/jetbrains/python/configuration/PyIntegratedToolsConfigurable.form
index 0d4c76ee4e78..358bf7e810c1 100644
--- a/python/src/com/jetbrains/python/configuration/PyIntegratedToolsConfigurable.form
+++ b/python/src/com/jetbrains/python/configuration/PyIntegratedToolsConfigurable.form
@@ -1,9 +1,9 @@
-
+
-
+
@@ -52,7 +52,7 @@
-
+
@@ -95,7 +95,7 @@
-
+
@@ -125,14 +125,6 @@
-
-
-
-
-
-
-
-
diff --git a/python/src/com/jetbrains/python/configuration/PyIntegratedToolsConfigurable.java b/python/src/com/jetbrains/python/configuration/PyIntegratedToolsConfigurable.java
index a402a58bd88c..c519eda530ce 100644
--- a/python/src/com/jetbrains/python/configuration/PyIntegratedToolsConfigurable.java
+++ b/python/src/com/jetbrains/python/configuration/PyIntegratedToolsConfigurable.java
@@ -41,7 +41,6 @@ import com.intellij.util.FileContentUtilCore;
import com.jetbrains.python.PyBundle;
import com.jetbrains.python.PythonFileType;
import com.jetbrains.python.ReSTService;
-import com.jetbrains.python.actions.PySciProjectComponent;
import com.jetbrains.python.documentation.PyDocumentationSettings;
import com.jetbrains.python.documentation.docstrings.DocStringFormat;
import com.jetbrains.python.packaging.PyPackageManagerUI;
@@ -79,7 +78,6 @@ public class PyIntegratedToolsConfigurable implements SearchableConfigurable {
private JPanel myDocStringsPanel;
private JPanel myRestPanel;
private JCheckBox renderExternal;
- private JCheckBox myShowPlots;
public PyIntegratedToolsConfigurable(@NotNull Module module) {
myModule = module;
@@ -102,7 +100,6 @@ public class PyIntegratedToolsConfigurable implements SearchableConfigurable {
txtIsRst.setSelected(service.txtIsRst());
analyzeDoctest.setSelected(myDocumentationSettings.isAnalyzeDoctest());
renderExternal.setSelected(myDocumentationSettings.isRenderExternalDocumentation());
- myShowPlots.setSelected(PySciProjectComponent.getInstance(myProject).matplotlibInToolwindow());
myRequirementsPathField.addBrowseFolderListener("Choose path to the package requirements file:", null, myProject,
FileChooserDescriptorFactory.createSingleLocalFileDescriptor());
myRequirementsPathField.setText(getRequirementsPath());
@@ -214,9 +211,6 @@ public class PyIntegratedToolsConfigurable implements SearchableConfigurable {
if (renderExternal.isSelected() != myDocumentationSettings.isRenderExternalDocumentation()) {
return true;
}
- if (myShowPlots.isSelected() != PySciProjectComponent.getInstance(myProject).matplotlibInToolwindow()) {
- return true;
- }
if (!ReSTService.getInstance(myModule).getWorkdir().equals(myWorkDir.getText())) {
return true;
}
@@ -246,7 +240,6 @@ public class PyIntegratedToolsConfigurable implements SearchableConfigurable {
}
myModel.apply();
myDocumentationSettings.setRenderExternalDocumentation(renderExternal.isSelected());
- PySciProjectComponent.getInstance(myProject).matplotlibInToolwindow(myShowPlots.isSelected());
myDocumentationSettings.setFormat((DocStringFormat)myDocstringFormatComboBox.getSelectedItem());
final ReSTService reSTService = ReSTService.getInstance(myModule);
reSTService.setWorkdir(myWorkDir.getText());
@@ -284,7 +277,6 @@ public class PyIntegratedToolsConfigurable implements SearchableConfigurable {
txtIsRst.setSelected(ReSTService.getInstance(myModule).txtIsRst());
analyzeDoctest.setSelected(myDocumentationSettings.isAnalyzeDoctest());
renderExternal.setSelected(myDocumentationSettings.isRenderExternalDocumentation());
- myShowPlots.setSelected(PySciProjectComponent.getInstance(myProject).matplotlibInToolwindow());
myRequirementsPathField.setText(getRequirementsPath());
}
diff --git a/python/src/com/jetbrains/python/debugger/containerview/PyDataView.java b/python/src/com/jetbrains/python/debugger/containerview/PyDataView.java
index 39a40d5507d3..b7c3a996a86d 100644
--- a/python/src/com/jetbrains/python/debugger/containerview/PyDataView.java
+++ b/python/src/com/jetbrains/python/debugger/containerview/PyDataView.java
@@ -65,7 +65,19 @@ public class PyDataView implements DumbAware {
myProject = project;
}
- public void show(@NotNull PyDebugValue value) {
+ public void show(@NotNull PyDebugValue value, boolean inToolwindow) {
+ if (inToolwindow) {
+ showInToolwindow(value);
+ }
+ else {
+ ApplicationManager.getApplication().invokeLater(() -> {
+ final PyDataViewDialog dialog = new PyDataViewDialog(myProject, value);
+ dialog.show();
+ });
+ }
+ }
+
+ private void showInToolwindow(@NotNull PyDebugValue value) {
ToolWindow window = ToolWindowManager.getInstance(myProject).getToolWindow(DATA_VIEWER_ID);
if (window == null) {
LOG.error("Tool window '" + DATA_VIEWER_ID + "' is not found");
diff --git a/python/src/com/jetbrains/python/debugger/containerview/PyDataViewDialog.java b/python/src/com/jetbrains/python/debugger/containerview/PyDataViewDialog.java
new file mode 100644
index 000000000000..43eba77843a3
--- /dev/null
+++ b/python/src/com/jetbrains/python/debugger/containerview/PyDataViewDialog.java
@@ -0,0 +1,78 @@
+/*
+ * 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.jetbrains.python.debugger.containerview;
+
+import com.intellij.ide.util.PropertiesComponent;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.DialogWrapper;
+import com.intellij.openapi.ui.VerticalFlowLayout;
+import com.intellij.ui.JBColor;
+import com.intellij.ui.components.JBCheckBox;
+import com.jetbrains.python.debugger.PyDebugValue;
+import org.jetbrains.annotations.NotNull;
+
+import javax.swing.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+public class PyDataViewDialog extends DialogWrapper {
+ private final JPanel myMainPanel;
+
+ PyDataViewDialog(@NotNull Project project, @NotNull final PyDebugValue value) {
+ super(project, false);
+ setModal(false);
+ setCancelButtonText("Close");
+ setCrossClosesWindow(true);
+ myMainPanel = new JPanel(new VerticalFlowLayout());
+ final PyDataViewerPanel panel = new PyDataViewerPanel(project, value.getFrameAccessor());
+ panel.apply(value);
+ myMainPanel.add(panel);
+ panel.setBorder(BorderFactory.createLineBorder(JBColor.GRAY));
+ final JBCheckBox colored = new JBCheckBox("Colored cells");
+ final JBCheckBox resize = new JBCheckBox("Resize Automatically");
+ resize.setSelected(PropertiesComponent.getInstance(project).getBoolean(PyDataView.AUTO_RESIZE, true));
+ colored.setSelected(PropertiesComponent.getInstance(project).getBoolean(PyDataView.COLORED_BY_DEFAULT, true));
+ colored.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ panel.setColored(colored.isSelected());
+ panel.updateUI();
+ }
+ });
+ resize.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ panel.resize(resize.isSelected());
+ panel.updateUI();
+ }
+ });
+ myMainPanel.add(colored);
+ myMainPanel.add(resize);
+ setTitle(value.getFullName());
+ init();
+ }
+
+ @Override
+ @NotNull
+ protected Action[] createActions() {
+ return new Action[]{getCancelAction()};
+ }
+
+ @Override
+ protected JComponent createCenterPanel() {
+ return myMainPanel;
+ }
+}
diff --git a/python/src/com/jetbrains/python/debugger/containerview/PyDataViewTabs.java b/python/src/com/jetbrains/python/debugger/containerview/PyDataViewTabs.java
index dbf48b678b93..ea2281aaeaf3 100644
--- a/python/src/com/jetbrains/python/debugger/containerview/PyDataViewTabs.java
+++ b/python/src/com/jetbrains/python/debugger/containerview/PyDataViewTabs.java
@@ -28,7 +28,7 @@ import org.jetbrains.annotations.Nullable;
import java.awt.*;
class PyDataViewTabs extends JBRunnerTabs {
-
+ public static final String EMPTY_TEXT = "Run debugger to view available data ";
private static final String HELP_ID = "reference.toolWindows.PyDataView";
public PyDataViewTabs(@NotNull Project project) {
@@ -40,7 +40,7 @@ class PyDataViewTabs extends JBRunnerTabs {
super.paintComponent(g);
if (isEmptyVisible()) {
UISettings.setupAntialiasing(g);
- UIUtil.drawCenteredString((Graphics2D)g, g.getClipBounds(), PyDataViewToolWindowFactory.EMPTY_TEXT);
+ UIUtil.drawCenteredString((Graphics2D)g, g.getClipBounds(), EMPTY_TEXT);
}
}
diff --git a/python/src/com/jetbrains/python/debugger/containerview/PyDataViewToolWindowFactory.java b/python/src/com/jetbrains/python/debugger/containerview/PyDataViewToolWindowFactory.java
deleted file mode 100644
index c0581567a040..000000000000
--- a/python/src/com/jetbrains/python/debugger/containerview/PyDataViewToolWindowFactory.java
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * 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.jetbrains.python.debugger.containerview;
-
-import com.intellij.execution.Executor;
-import com.intellij.execution.executors.DefaultDebugExecutor;
-import com.intellij.execution.process.ProcessHandler;
-import com.intellij.execution.ui.RunContentDescriptor;
-import com.intellij.execution.ui.RunContentManager;
-import com.intellij.execution.ui.RunContentWithExecutorListener;
-import com.intellij.ide.util.PropertiesComponent;
-import com.intellij.openapi.actionSystem.AnActionEvent;
-import com.intellij.openapi.actionSystem.DefaultActionGroup;
-import com.intellij.openapi.actionSystem.ToggleAction;
-import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.wm.ToolWindow;
-import com.intellij.openapi.wm.ToolWindowFactory;
-import com.intellij.openapi.wm.ToolWindowManager;
-import com.intellij.openapi.wm.ex.ToolWindowEx;
-import com.intellij.ui.content.ContentManagerAdapter;
-import com.intellij.ui.content.ContentManagerEvent;
-import com.intellij.util.messages.MessageBusConnection;
-import com.intellij.xdebugger.XDebugProcess;
-import com.intellij.xdebugger.XDebuggerManager;
-import com.intellij.xdebugger.XDebuggerManagerListener;
-import com.jetbrains.python.console.PythonConsoleToolWindowFactory;
-import com.jetbrains.python.debugger.PyDebugProcess;
-import com.jetbrains.python.plots.PyPlotToolWindow;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-public class PyDataViewToolWindowFactory implements ToolWindowFactory {
- public static final String EMPTY_TEXT = "Run debugger to view available data ";
- private static final Logger LOG = Logger.getInstance(PyDataViewToolWindowFactory.class);
-
- @Override
- public void createToolWindowContent(@NotNull Project project, @NotNull ToolWindow toolWindow) {
- initializeDataTab(project, toolWindow);
- PyPlotToolWindow.getInstance(project).init(toolWindow);
- }
-
- private static void initializeDataTab(@NotNull Project project, @NotNull ToolWindow toolWindow) {
- PyDataView.getInstance(project).init(toolWindow);
- final MessageBusConnection connection = project.getMessageBus().connect(project);
- connection.subscribe(XDebuggerManager.TOPIC, new ChangeContentXDebuggerManagerListener(project));
-
- connection.subscribe(RunContentManager.TOPIC, new RunContentWithExecutorListener() {
- @Override
- public void contentSelected(@Nullable RunContentDescriptor descriptor, @NotNull Executor executor) {
- if (!(executor instanceof DefaultDebugExecutor)) {
- return;
- }
- if (descriptor == null) {
- return;
- }
- ProcessHandler handler = descriptor.getProcessHandler();
- if (handler == null) {
- return;
- }
- PyDataView.getInstance(project).updateTabs(handler);
- }
-
- @Override
- public void contentRemoved(@Nullable RunContentDescriptor descriptor, @NotNull Executor executor) {
-
- }
- });
-
- addPythonConsoleListener(project);
- PyDataViewToggleAction autoResizeAction = new PyDataViewToggleAction("Resize Automatically", PyDataView.AUTO_RESIZE) {
- @Override
- public void setSelected(AnActionEvent e, boolean state) {
- super.setSelected(e, state);
- PyDataView.getInstance(project).changeAutoResize(state);
- }
- };
- DefaultActionGroup group = new DefaultActionGroup(new PyDataViewToggleAction("Colored by Default", PyDataView.COLORED_BY_DEFAULT),
- autoResizeAction);
- ((ToolWindowEx)toolWindow).setAdditionalGearActions(group);
- }
-
- private static void addPythonConsoleListener(@NotNull Project project) {
- final ToolWindow pythonConsole = ToolWindowManager.getInstance(project).getToolWindow(PythonConsoleToolWindowFactory.Companion.getID());
- if (pythonConsole == null) {
- return;
- }
- pythonConsole.getContentManager().addContentManagerListener(new ContentManagerAdapter() {
- @Override
- public void contentRemoved(ContentManagerEvent event) {
- PyDataView.getInstance(project).closeDisconnectedFromConsoleTabs();
- }
- });
- }
-
- private static class PyDataViewToggleAction extends ToggleAction {
- private final String myPropertyKey;
-
- public PyDataViewToggleAction(String text, String propertyKey) {
- super(text);
- myPropertyKey = propertyKey;
- }
-
- @Override
- public boolean isSelected(AnActionEvent e) {
- return PropertiesComponent.getInstance(e.getProject()).getBoolean(myPropertyKey, true);
- }
-
- @Override
- public void setSelected(AnActionEvent e, boolean state) {
- PropertiesComponent.getInstance(e.getProject()).setValue(myPropertyKey, state, true);
- }
- }
-
- private static class ChangeContentXDebuggerManagerListener implements XDebuggerManagerListener {
- private final Project myProject;
-
- public ChangeContentXDebuggerManagerListener(Project project) {
- myProject = project;
- }
-
- @Override
- public void processStarted(@NotNull XDebugProcess debugProcess) {
-
- }
-
- @Override
- public void processStopped(@NotNull XDebugProcess debugProcess) {
- if (debugProcess instanceof PyDebugProcess) {
- PyDataView.getInstance(myProject).closeTabs(frameAccessor -> frameAccessor instanceof PyDebugProcess && frameAccessor == debugProcess);
- }
- }
- }
-}
diff --git a/python/src/com/jetbrains/python/debugger/containerview/PyViewNumericContainerAction.java b/python/src/com/jetbrains/python/debugger/containerview/PyViewNumericContainerAction.java
index 011537ed61b3..71886da63719 100644
--- a/python/src/com/jetbrains/python/debugger/containerview/PyViewNumericContainerAction.java
+++ b/python/src/com/jetbrains/python/debugger/containerview/PyViewNumericContainerAction.java
@@ -18,6 +18,7 @@ package com.jetbrains.python.debugger.containerview;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.project.Project;
+import com.intellij.util.PlatformUtils;
import com.intellij.xdebugger.impl.ui.tree.XDebuggerTree;
import com.intellij.xdebugger.impl.ui.tree.actions.XDebuggerTreeActionBase;
import com.intellij.xdebugger.impl.ui.tree.nodes.XValueNodeImpl;
@@ -43,7 +44,7 @@ public class PyViewNumericContainerAction extends XDebuggerTreeActionBase {
}
public static void showNumericViewer(Project project, PyDebugValue debugValue) {
- PyDataView.getInstance(project).show(debugValue);
+ PyDataView.getInstance(project).show(debugValue, PlatformUtils.isPyCharmPro());
}
@Nullable
diff --git a/python/src/com/jetbrains/python/inspections/PySciViewAdvertiser.java b/python/src/com/jetbrains/python/inspections/PySciViewAdvertiser.java
deleted file mode 100644
index 2c238f03ed19..000000000000
--- a/python/src/com/jetbrains/python/inspections/PySciViewAdvertiser.java
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * 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.jetbrains.python.inspections;
-
-import com.intellij.ide.DataManager;
-import com.intellij.lang.annotation.AnnotationHolder;
-import com.intellij.lang.annotation.Annotator;
-import com.intellij.notification.NotificationDisplayType;
-import com.intellij.notification.NotificationGroup;
-import com.intellij.notification.NotificationListener;
-import com.intellij.notification.NotificationType;
-import com.intellij.openapi.actionSystem.ActionManager;
-import com.intellij.openapi.actionSystem.ActionPlaces;
-import com.intellij.openapi.actionSystem.AnAction;
-import com.intellij.openapi.actionSystem.AnActionEvent;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.roots.FileIndexFacade;
-import com.intellij.openapi.util.Key;
-import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.psi.PsiElement;
-import com.intellij.psi.util.QualifiedName;
-import com.jetbrains.python.actions.PySciProjectComponent;
-import com.jetbrains.python.actions.PySciViewAction;
-import com.jetbrains.python.psi.PyFile;
-import com.jetbrains.python.psi.PyImportElement;
-import org.jetbrains.annotations.NotNull;
-
-import static com.jetbrains.python.actions.PySciViewAction.ACTION_ID;
-
-public class PySciViewAdvertiser implements Annotator {
-
- private static final NotificationGroup BALLOON_NOTIFICATIONS = new NotificationGroup("Python Scientific View Advertiser",
- NotificationDisplayType.STICKY_BALLOON, false);
- private static final Key BALLOON_SHOWING = Key.create("showingSciViewAdvertiserBalloon");
-
- @Override
- public void annotate(@NotNull PsiElement element, @NotNull AnnotationHolder holder) {
- if (element instanceof PyFile) {
- final PyFile pyFile = (PyFile)element;
- final Project project = element.getProject();
-
- if (PySciProjectComponent.getInstance(project).sciViewSuggested()) {
- return;
- }
- final VirtualFile vFile = pyFile.getVirtualFile();
- if (vFile != null && FileIndexFacade.getInstance(project).isInLibraryClasses(vFile)) {
- return;
- }
-
- final Boolean showingFlag = project.getUserData(BALLOON_SHOWING);
- if (showingFlag != null && showingFlag.booleanValue()) {
- return;
- }
-
- if (containsNumpyImports(pyFile)) {
- showInspectionAdvertisement(project);
- }
- }
- }
-
- private static void showInspectionAdvertisement(@NotNull Project project) {
- final String msg = "Your source code imports the 'numpy' package." +
- "
Would you like to enable Scientific View?
" +
- "Yes No";
- showSingletonNotification(project, msg, NotificationType.INFORMATION, (notification, event) -> {
- final boolean enabled = "#yes".equals(event.getDescription());
- PySciProjectComponent.getInstance(project).sciViewSuggested(true);
- if (enabled) {
- final AnAction action = ActionManager.getInstance().getAction(ACTION_ID);
- if (action instanceof PySciViewAction) {
- PySciProjectComponent.getInstance(project).sciViewSuggested();
- final AnActionEvent anActionEvent = AnActionEvent.createFromDataContext(
- ActionPlaces.UNKNOWN, null, DataManager.getInstance().getDataContextFromFocus().getResult());
- ((PySciViewAction)action).setSelected(anActionEvent, true);
- }
- }
- });
- }
-
- private static void showSingletonNotification(@NotNull Project project,
- @NotNull String htmlContent,
- @NotNull NotificationType type,
- @NotNull NotificationListener listener) {
- project.putUserData(BALLOON_SHOWING, true);
- BALLOON_NOTIFICATIONS.createNotification("Scientific View", htmlContent, type, (notification, event) -> {
- try {
- listener.hyperlinkUpdate(notification, event);
- }
- finally {
- notification.expire();
- }
- }).notify(project);
- }
-
- private static boolean containsNumpyImports(@NotNull PyFile file) {
- for (PyImportElement importTarget : file.getImportTargets()) {
- final QualifiedName qName = importTarget.getImportedQName();
- if (qName != null && qName.matches("numpy")) {
- return true;
- }
- }
- return false;
- }
-
-}
diff --git a/python/src/com/jetbrains/python/plots/PyPlotToolWindow.java b/python/src/com/jetbrains/python/plots/PyPlotToolWindow.java
deleted file mode 100644
index 286abedec088..000000000000
--- a/python/src/com/jetbrains/python/plots/PyPlotToolWindow.java
+++ /dev/null
@@ -1,355 +0,0 @@
-/*
- * Copyright 2000-2013 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.plots;
-
-import com.intellij.icons.AllIcons;
-import com.intellij.openapi.Disposable;
-import com.intellij.openapi.actionSystem.*;
-import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.components.ServiceManager;
-import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.fileChooser.FileChooserFactory;
-import com.intellij.openapi.fileChooser.FileSaverDescriptor;
-import com.intellij.openapi.fileChooser.FileSaverDialog;
-import com.intellij.openapi.fileEditor.FileEditor;
-import com.intellij.openapi.fileEditor.FileEditorProvider;
-import com.intellij.openapi.fileEditor.ex.FileEditorProviderManager;
-import com.intellij.openapi.fileEditor.impl.EditorTabbedContainer;
-import com.intellij.openapi.project.DumbAware;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.Disposer;
-import com.intellij.openapi.vfs.VirtualFileWrapper;
-import com.intellij.openapi.wm.IdeFocusManager;
-import com.intellij.openapi.wm.ToolWindow;
-import com.intellij.testFramework.BinaryLightVirtualFile;
-import com.intellij.ui.JBColor;
-import com.intellij.ui.SimpleColoredComponent;
-import com.intellij.ui.awt.RelativePoint;
-import com.intellij.ui.awt.RelativeRectangle;
-import com.intellij.ui.content.Content;
-import com.intellij.ui.content.ContentFactory;
-import com.intellij.ui.docking.DockContainer;
-import com.intellij.ui.docking.DockManager;
-import com.intellij.ui.docking.DockableContent;
-import com.intellij.ui.docking.DragSession;
-import com.intellij.ui.tabs.JBTabsPosition;
-import com.intellij.ui.tabs.TabInfo;
-import com.intellij.ui.tabs.impl.DefaultEditorTabsPainter;
-import com.intellij.ui.tabs.impl.JBEditorTabs;
-import com.intellij.ui.tabs.impl.JBTabsImpl;
-import com.intellij.ui.tabs.impl.TabLabel;
-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 java.awt.*;
-import java.awt.event.MouseEvent;
-import java.awt.image.BufferedImage;
-import java.io.File;
-import java.io.IOException;
-import java.nio.file.Files;
-import java.nio.file.Paths;
-
-public class PyPlotToolWindow extends JPanel implements DumbAware {
- public static final String PLOT_DEFAULT_NAME = "myplot";
- public static final String PLOT_FORMAT = "png";
- private final static int ourPreviewSize = 80;
-
- private final JBEditorTabs myTabs;
- private final Project myProject;
-
- private static final Logger LOG = Logger.getInstance(PyPlotToolWindow.class);
- private MyDockContainer myDockContainer;
-
- public PyPlotToolWindow(final Project project) {
- super(new BorderLayout());
- myProject = project;
- myTabs = new MyTabs(myProject);
- myTabs.setTabsPosition(JBTabsPosition.right);
- myTabs.setPopupGroup(new DefaultActionGroup(new SaveAsFileAction()), ActionPlaces.UNKNOWN, true);
- myTabs.setTabDraggingEnabled(true);
- add(myTabs);
- }
-
- public void onMessage(int width, byte[] raw) {
- final PyPlotVirtualFile plotVirtualFile = new PyPlotVirtualFile(width, raw);
- final TabInfo info = createTabInfo(plotVirtualFile);
-
- ApplicationManager.getApplication().invokeLater(() -> {
- myTabs.addTab(info);
- myTabs.select(info, true);
- });
- }
-
- @NotNull
- private TabInfo createTabInfo(@NotNull final PyPlotVirtualFile plotVirtualFile) {
- final JPanel panel = new MyPlotPanel(plotVirtualFile);
- final TabInfo info = new TabInfo(panel);
- info.setTabColor(UIUtil.getPanelBackground());
- final BufferedImage image = plotVirtualFile.getImage();
- final Image after = image.getScaledInstance(JBUI.scale(64), JBUI.scale(48), Image.SCALE_SMOOTH);
- info.setIcon(new ImageIcon(after));
- info.setText(" ");
- info.setTabLabelActions(new DefaultActionGroup(new ClosePlotAction(info)), ActionPlaces.UNKNOWN);
- info.setDragOutDelegate(new MyDragOutDelegate());
- return info;
- }
-
- public void init(ToolWindow toolWindow) {
- final ContentFactory contentFactory = ContentFactory.SERVICE.getInstance();
- Content content = contentFactory.createContent(this, "Plots", false);
- content.setCloseable(false);
- toolWindow.getContentManager().addContent(content);
-
- if (myDockContainer == null) {
- myDockContainer = new MyDockContainer(toolWindow);
- Disposer.register(myProject, myDockContainer);
- DockManager.getInstance(myProject).register(myDockContainer);
- }
- }
-
- public static PyPlotToolWindow getInstance(@NotNull final Project project) {
- return ServiceManager.getService(project, PyPlotToolWindow.class);
- }
-
- private static class MyTabs extends JBEditorTabs {
- public MyTabs(Project project) {
- super(project, ActionManager.getInstance(), IdeFocusManager.findInstance(), project);
- myDefaultPainter = new DefaultEditorTabsPainter(this) {
- @Override
- public Color getBackgroundColor() {
- return JBColor.LIGHT_GRAY;
- }
- };
- }
-
- @Override
- protected TabLabel createTabLabel(TabInfo info) {
- return new MyTabLabel(this, info);
- }
- }
-
- private static class MyTabLabel extends TabLabel {
- public MyTabLabel(JBTabsImpl tabs, TabInfo info) {
- super(tabs, info);
- final JComponent label = getLabelComponent();
- if (label instanceof SimpleColoredComponent) {
- ((SimpleColoredComponent)label).setIconOnTheRight(true);
- }
- }
-
- @Override
- public Dimension getPreferredSize() {
- return new Dimension(JBUI.scale(ourPreviewSize + 20), JBUI.scale(ourPreviewSize));
- }
- }
-
- private class ClosePlotAction extends AnAction {
- private final TabInfo myInfo;
-
- public ClosePlotAction(TabInfo info) {
- super("Close Plot", "Close selected plot", AllIcons.Actions.Close);
- myInfo = info;
- }
-
- @Override
- public void actionPerformed(AnActionEvent e) {
- myTabs.removeTab(myInfo);
- }
- }
-
- private class SaveAsFileAction extends AnAction {
- public SaveAsFileAction() {
- super("Save as File");
- }
-
- @Override
- public void actionPerformed(AnActionEvent e) {
- TabInfo info = myTabs.getSelectedInfo();
- final Project project = e.getProject();
- if (info != null && project != null) {
- final MyPlotPanel component = (MyPlotPanel)info.getComponent();
- final BinaryLightVirtualFile virtualFile = component.getVirtualFile();
-
- FileSaverDescriptor descriptor = new FileSaverDescriptor("Select File to Save Plot", "", PLOT_FORMAT);
- final FileSaverDialog chooser = FileChooserFactory.getInstance().createSaveFileDialog(descriptor, project);
-
- final VirtualFileWrapper fileWrapper = chooser.save(project.getBaseDir(), PLOT_DEFAULT_NAME);
- try {
- if (fileWrapper != null) {
- final File ioFile = fileWrapper.getFile();
- Files.write(Paths.get(ioFile.getPath()), virtualFile.getContent());
- }
- }
- catch (IOException e1) {
- LOG.warn("Failed to save image " + e1.getMessage());
- }
- }
- }
- }
-
- private class MyPlotPanel extends JPanel {
- private final PyPlotVirtualFile myVirtualFile;
-
- public MyPlotPanel(PyPlotVirtualFile virtualFile) {
- super(new BorderLayout());
- myVirtualFile = virtualFile;
- ApplicationManager.getApplication().invokeLater(() -> {
- //ImageFileEditorProvider#EDITOR_TYPE_ID
- final FileEditorProvider provider = FileEditorProviderManager.getInstance().getProvider("images");
- if (provider != null) {
- final FileEditor editor = provider.createEditor(myProject, myVirtualFile);
- Disposer.register(myProject, editor);
- add(editor.getComponent());
- }
- });
-
- setBackground(UIUtil.getEditorPaneBackground());
- }
-
- public BinaryLightVirtualFile getVirtualFile() {
- return myVirtualFile;
- }
- }
-
- class MyDragOutDelegate implements TabInfo.DragOutDelegate {
- private DragSession mySession;
-
- @Override
- public void dragOutStarted(MouseEvent mouseEvent, TabInfo info) {
- final TabInfo previousSelection = info.getPreviousSelection();
- final Image img = JBTabsImpl.getComponentImage(info);
- info.setHidden(true);
- if (previousSelection != null) {
- myTabs.select(previousSelection, true);
- }
-
- Presentation presentation = new Presentation(info.getText());
- presentation.setIcon(info.getIcon());
- final MyPlotPanel component = (MyPlotPanel)info.getComponent();
- final BinaryLightVirtualFile file = component.getVirtualFile();
- mySession = getDockManager().createDragSession(mouseEvent, new EditorTabbedContainer.DockableEditor(myProject, img, file, presentation,
- info.getComponent().getPreferredSize(), false));
-
- }
-
- private DockManager getDockManager() {
- return DockManager.getInstance(myProject);
- }
-
- @Override
- public void processDragOut(MouseEvent event, TabInfo source) {
- mySession.process(event);
- }
-
- @Override
- public void dragOutFinished(MouseEvent event, TabInfo source) {
- myTabs.removeTab(source);
- mySession.process(event);
- mySession = null;
- }
-
- @Override
- public void dragOutCancelled(TabInfo source) {
- source.setHidden(false);
- if (mySession != null) {
- mySession.cancel();
- }
- mySession = null;
- }
- }
-
- public class MyDockContainer implements DockContainer {
- private final ToolWindow myToolWindow;
-
- public MyDockContainer(ToolWindow toolWindow) {
- myToolWindow = toolWindow;
- }
-
- @Override
- public RelativeRectangle getAcceptArea() {
- return new RelativeRectangle(myToolWindow.getComponent());
- }
-
- @Override
- public RelativeRectangle getAcceptAreaFallback() {
- return getAcceptArea();
- }
-
- @NotNull
- @Override
- public ContentResponse getContentResponse(@NotNull DockableContent content, RelativePoint point) {
- return content.getKey() instanceof PyPlotVirtualFile ? ContentResponse.ACCEPT_MOVE : ContentResponse.DENY;
- }
-
- @Override
- public JComponent getContainerComponent() {
- return myToolWindow.getComponent();
- }
-
- @Override
- public void add(@NotNull DockableContent content, RelativePoint dropTarget) {
- final Object key = content.getKey();
- if (key instanceof PyPlotVirtualFile) {
- final TabInfo info = createTabInfo((PyPlotVirtualFile)key);
- myTabs.addTab(info);
- }
- }
-
- @Override
- public void closeAll() {}
-
- @Override
- public void addListener(Listener listener, Disposable parent) {}
-
- @Override
- public boolean isEmpty() {
- return false;
- }
-
- @Nullable
- @Override
- public Image startDropOver(@NotNull DockableContent content, RelativePoint point) {
- return null;
- }
-
- @Nullable
- @Override
- public Image processDropOver(@NotNull DockableContent content, RelativePoint point) {
- return null;
- }
-
- @Override
- public void resetDropOver(@NotNull DockableContent content) {}
-
- @Override
- public boolean isDisposeWhenEmpty() {
- return false;
- }
-
- @Override
- public void dispose() {}
-
- @Override
- public void showNotify() {}
-
- @Override
- public void hideNotify() {}
- }
-}
diff --git a/python/src/com/jetbrains/python/plots/PyPlotVirtualFile.java b/python/src/com/jetbrains/python/plots/PyPlotVirtualFile.java
deleted file mode 100644
index 387c2a755633..000000000000
--- a/python/src/com/jetbrains/python/plots/PyPlotVirtualFile.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright 2000-2013 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.plots;
-
-import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.util.SystemInfo;
-import com.intellij.testFramework.BinaryLightVirtualFile;
-import com.intellij.util.ui.UIUtil;
-
-import javax.imageio.ImageIO;
-import java.awt.image.*;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-
-public class PyPlotVirtualFile extends BinaryLightVirtualFile {
- private static final Logger LOG = Logger.getInstance(PyPlotToolWindow.class);
- private BufferedImage myImage;
-
- public PyPlotVirtualFile(int width, byte[] raw) {
- super(PyPlotToolWindow.PLOT_DEFAULT_NAME + "." + PyPlotToolWindow.PLOT_FORMAT);
-
- int height = raw.length / 3 / width;
- final DataBuffer buffer = new DataBufferByte(raw, raw.length);
- final SampleModel sampleModel = new ComponentSampleModel(DataBuffer.TYPE_BYTE, width, height, 3, width * 3,
- new int[]{0, 1, 2});
- final Raster raster = Raster.createRaster(sampleModel, buffer, null);
- myImage = UIUtil.createImage(width, height, BufferedImage.TYPE_INT_RGB);
- if (SystemInfo.isMac && UIUtil.isRetina()) {
- myImage = myImage.getSubimage(0, 0, width / 2, height / 2);
- }
- myImage.setData(raster);
- byte[] bytes = imageToByteArray(myImage);
- if (bytes == null) return;
- ApplicationManager.getApplication().invokeLater(() -> {
- ApplicationManager.getApplication().runWriteAction(() -> {
- try {
- setBinaryContent(bytes);
- }
- catch (IOException ignored) {
- }
- });
- });
- }
-
- public BufferedImage getImage() {
- return myImage;
- }
-
- public static byte[] imageToByteArray(BufferedImage image) {
- ByteArrayOutputStream stream = new ByteArrayOutputStream();
- try {
- ImageIO.write(image, PyPlotToolWindow.PLOT_FORMAT, stream);
- stream.flush();
- byte[] imageInByte = stream.toByteArray();
- stream.close();
- return imageInByte;
- }
- catch (IOException e) {
- LOG.warn("Failed to convert image to byte array " + e.getMessage());
- }
- return null;
- }
-}
diff --git a/python/src/com/jetbrains/python/run/PythonCommandLineEnvironmentProvider.java b/python/src/com/jetbrains/python/run/PythonCommandLineEnvironmentProvider.java
new file mode 100644
index 000000000000..2aa2f95bdbbd
--- /dev/null
+++ b/python/src/com/jetbrains/python/run/PythonCommandLineEnvironmentProvider.java
@@ -0,0 +1,28 @@
+/*
+ * 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.run;
+
+import com.intellij.execution.configurations.GeneralCommandLine;
+import com.intellij.openapi.extensions.ExtensionPointName;
+import com.intellij.openapi.project.Project;
+import org.jetbrains.annotations.NotNull;
+
+public interface PythonCommandLineEnvironmentProvider {
+ ExtensionPointName EP_NAME =
+ ExtensionPointName.create("Pythonid.pythonCommandLineEnvironmentProvider");
+
+ void extendEnvironment(@NotNull Project project, @NotNull GeneralCommandLine cmdLine);
+}
diff --git a/python/src/com/jetbrains/python/run/PythonCommandLineState.java b/python/src/com/jetbrains/python/run/PythonCommandLineState.java
index eee676c67657..0868d6bc330e 100644
--- a/python/src/com/jetbrains/python/run/PythonCommandLineState.java
+++ b/python/src/com/jetbrains/python/run/PythonCommandLineState.java
@@ -36,6 +36,7 @@ import com.intellij.execution.ui.ConsoleView;
import com.intellij.facet.Facet;
import com.intellij.facet.FacetManager;
import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.module.ModuleUtilCore;
@@ -54,7 +55,6 @@ import com.intellij.openapi.vfs.encoding.EncodingProjectManager;
import com.intellij.remote.RemoteProcessControl;
import com.intellij.util.PlatformUtils;
import com.jetbrains.python.PythonHelpersLocator;
-import com.jetbrains.python.actions.PySciProjectComponent;
import com.jetbrains.python.console.PyDebugConsoleBuilder;
import com.jetbrains.python.debugger.PyDebugRunner;
import com.jetbrains.python.debugger.PyDebuggerOptionsProvider;
@@ -325,10 +325,6 @@ public abstract class PythonCommandLineState extends CommandLineState {
if (myConfig.getEnvs() != null) {
env.putAll(myConfig.getEnvs());
}
- if (PySciProjectComponent.getInstance(project).matplotlibInToolwindow() &&
- PySciProjectComponent.getInstance(project).getPort() != -1) {
- env.put("PYCHARM_MATPLOTLIB_PORT", String.valueOf(PySciProjectComponent.getInstance(project).getPort()));
- }
addCommonEnvironmentVariables(getInterpreterPath(project, myConfig), env);
setupVirtualEnvVariables(myConfig, env, myConfig.getSdkHome());
@@ -337,8 +333,11 @@ public abstract class PythonCommandLineState extends CommandLineState {
commandLine.getEnvironment().putAll(env);
commandLine.withParentEnvironmentType(myConfig.isPassParentEnvs() ? ParentEnvironmentType.CONSOLE : ParentEnvironmentType.NONE);
-
buildPythonPath(project, commandLine, myConfig, isDebug);
+
+ for (PythonCommandLineEnvironmentProvider envProvider : Extensions.getExtensions(PythonCommandLineEnvironmentProvider.EP_NAME)) {
+ envProvider.extendEnvironment(project, commandLine);
+ }
}
private static void setupVirtualEnvVariables(PythonRunParams myConfig, Map env, String sdkHome) {
@@ -385,10 +384,6 @@ public abstract class PythonCommandLineState extends CommandLineState {
Sdk pythonSdk = PythonSdkType.findSdkByPath(config.getSdkHome());
if (pythonSdk != null) {
List pathList = Lists.newArrayList();
- if (PySciProjectComponent.getInstance(project).matplotlibInToolwindow() &&
- PySciProjectComponent.getInstance(project).getPort() != -1) {
- pathList.add(PythonHelpersLocator.getHelperPath("pycharm_matplotlib_backend"));
- }
pathList.addAll(getAddedPaths(pythonSdk));
pathList.addAll(collectPythonPath(project, config, isDebug));
initPythonPath(commandLine, config.isPassParentEnvs(), pathList, config.getSdkHome());