summaryrefslogtreecommitdiff
path: root/python/edu/src
diff options
context:
space:
mode:
Diffstat (limited to 'python/edu/src')
-rw-r--r--python/edu/src/META-INF/PyCharmEduPlugin.xml10
-rw-r--r--python/edu/src/com/intellij/openapi/application/PyCharmEduConfigImportSettings.java12
-rw-r--r--python/edu/src/com/jetbrains/python/edu/PyCharmEduInitialConfigurator.java45
-rw-r--r--python/edu/src/com/jetbrains/python/edu/PyExecuteFileLineMarkerProvider.java91
-rw-r--r--python/edu/src/com/jetbrains/python/edu/PyRunCurrentFileAction.java56
5 files changed, 207 insertions, 7 deletions
diff --git a/python/edu/src/META-INF/PyCharmEduPlugin.xml b/python/edu/src/META-INF/PyCharmEduPlugin.xml
index d5b2fdfe8c28..87739a948968 100644
--- a/python/edu/src/META-INF/PyCharmEduPlugin.xml
+++ b/python/edu/src/META-INF/PyCharmEduPlugin.xml
@@ -19,6 +19,10 @@
</component>
</application-components>
+ <extensions defaultExtensionNs="com.intellij">
+ <codeInsight.lineMarkerProvider language="Python" implementationClass="com.jetbrains.python.edu.PyExecuteFileLineMarkerProvider"/>
+ </extensions>
+
<actions>
<group overrides="true" class="com.intellij.openapi.actionSystem.EmptyActionGroup" id="ToolsMenu"/>
@@ -38,5 +42,11 @@
<action overrides="true" class="com.intellij.openapi.actionSystem.EmptyAction" id="NewHtmlFile"/>
+ <group id="PyRunMenu">
+ <action id="runCurrentFile" class="com.jetbrains.python.edu.PyRunCurrentFileAction"/>
+ <add-to-group group-id="RunMenu" anchor="first"/>
+ </group>
+
+
</actions>
</idea-plugin>
diff --git a/python/edu/src/com/intellij/openapi/application/PyCharmEduConfigImportSettings.java b/python/edu/src/com/intellij/openapi/application/PyCharmEduConfigImportSettings.java
new file mode 100644
index 000000000000..989c750681f3
--- /dev/null
+++ b/python/edu/src/com/intellij/openapi/application/PyCharmEduConfigImportSettings.java
@@ -0,0 +1,12 @@
+package com.intellij.openapi.application;
+
+import com.intellij.ide.plugins.PluginManagerCore;
+
+// see com.intellij.openapi.application.ConfigImportHelper.getConfigImportSettings
+@SuppressWarnings("UnusedDeclaration")
+public class PyCharmEduConfigImportSettings extends ConfigImportSettings {
+ public PyCharmEduConfigImportSettings() {
+ PluginManagerCore.disablePlugin("org.jetbrains.plugins.coursecreator");
+ }
+
+}
diff --git a/python/edu/src/com/jetbrains/python/edu/PyCharmEduInitialConfigurator.java b/python/edu/src/com/jetbrains/python/edu/PyCharmEduInitialConfigurator.java
index ecf3d79a6424..2954f7c5b706 100644
--- a/python/edu/src/com/jetbrains/python/edu/PyCharmEduInitialConfigurator.java
+++ b/python/edu/src/com/jetbrains/python/edu/PyCharmEduInitialConfigurator.java
@@ -35,14 +35,15 @@ import com.intellij.openapi.fileTypes.FileTypeManager;
import com.intellij.openapi.keymap.Keymap;
import com.intellij.openapi.keymap.ex.KeymapManagerEx;
import com.intellij.openapi.keymap.impl.KeymapImpl;
+import com.intellij.openapi.project.DumbAwareRunnable;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
import com.intellij.openapi.project.ProjectManagerAdapter;
import com.intellij.openapi.project.ex.ProjectManagerEx;
+import com.intellij.openapi.startup.StartupManager;
+import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.vfs.VfsUtil;
-import com.intellij.openapi.wm.ToolWindowEP;
-import com.intellij.openapi.wm.ToolWindowId;
-import com.intellij.openapi.wm.WindowManager;
+import com.intellij.openapi.wm.*;
import com.intellij.platform.DirectoryProjectConfigurator;
import com.intellij.platform.PlatformProjectViewOpener;
import com.intellij.psi.codeStyle.CodeStyleSettings;
@@ -62,9 +63,9 @@ import java.util.Set;
*/
@SuppressWarnings({"UtilityClassWithoutPrivateConstructor", "UtilityClassWithPublicConstructor"})
public class PyCharmEduInitialConfigurator {
- @NonNls private static final String DISPLAYED_PROPERTY = "PyCharm.initialConfigurationShown";
+ @NonNls private static final String DISPLAYED_PROPERTY = "PyCharmEDU.initialConfigurationShown";
- @NonNls private static final String CONFIGURED = "PyCharm.InitialConfiguration";
+ @NonNls private static final String CONFIGURED = "PyCharmEDU.InitialConfiguration";
public static class First {
@@ -93,6 +94,8 @@ public class PyCharmEduInitialConfigurator {
uiSettings.SHOW_MAIN_TOOLBAR = false;
codeInsightSettings.REFORMAT_ON_PASTE = CodeInsightSettings.NO_REFORMAT;
+ Registry.get("ide.new.settings.dialog").setValue(true);
+
GeneralSettings.getInstance().setShowTipsOnStartup(false);
EditorSettingsExternalizable.getInstance().setVirtualSpace(false);
@@ -113,7 +116,7 @@ public class PyCharmEduInitialConfigurator {
});
}
});
- PyCodeInsightSettings.getInstance().SHOW_IMPORT_POPUP = true;
+ PyCodeInsightSettings.getInstance().SHOW_IMPORT_POPUP = false;
}
if (!propertiesComponent.isValueSet(DISPLAYED_PROPERTY)) {
@@ -147,6 +150,29 @@ public class PyCharmEduInitialConfigurator {
}
patchProjectAreaExtensions(project);
+
+ StartupManager.getInstance(project).runWhenProjectIsInitialized(new DumbAwareRunnable() {
+ @Override
+ public void run() {
+ if (project.isDisposed()) return;
+
+ ToolWindowManager.getInstance(project).invokeLater(new Runnable() {
+ int count = 0;
+
+ public void run() {
+ if (project.isDisposed()) return;
+ if (count++ < 3) { // we need to call this after ToolWindowManagerImpl.registerToolWindowsFromBeans
+ ToolWindowManager.getInstance(project).invokeLater(this);
+ return;
+ }
+ ToolWindow toolWindow = ToolWindowManager.getInstance(project).getToolWindow("Project");
+ if (toolWindow.getType() != ToolWindowType.SLIDING) {
+ toolWindow.activate(null);
+ }
+ }
+ });
+ }
+ });
}
});
}
@@ -205,6 +231,11 @@ public class PyCharmEduInitialConfigurator {
private static void showInitialConfigurationDialog() {
final JFrame frame = WindowManager.getInstance().findVisibleFrame();
- new InitialConfigurationDialog(frame, "Python").show();
+ new InitialConfigurationDialog(frame, "Python") {
+ @Override
+ protected boolean canCreateLauncherScript() {
+ return false;
+ }
+ }.show();
}
}
diff --git a/python/edu/src/com/jetbrains/python/edu/PyExecuteFileLineMarkerProvider.java b/python/edu/src/com/jetbrains/python/edu/PyExecuteFileLineMarkerProvider.java
new file mode 100644
index 000000000000..03522bb8cf8a
--- /dev/null
+++ b/python/edu/src/com/jetbrains/python/edu/PyExecuteFileLineMarkerProvider.java
@@ -0,0 +1,91 @@
+package com.jetbrains.python.edu;
+
+import com.intellij.codeHighlighting.Pass;
+import com.intellij.codeInsight.daemon.GutterIconNavigationHandler;
+import com.intellij.codeInsight.daemon.LineMarkerInfo;
+import com.intellij.codeInsight.daemon.LineMarkerProvider;
+import com.intellij.execution.actions.ConfigurationContext;
+import com.intellij.icons.AllIcons;
+import com.intellij.ide.DataManager;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.editor.markup.GutterIconRenderer;
+import com.intellij.psi.PsiComment;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiWhiteSpace;
+import com.intellij.psi.util.PsiUtilBase;
+import com.intellij.util.Function;
+import com.jetbrains.python.psi.PyFile;
+import com.jetbrains.python.psi.PyImportStatement;
+import com.jetbrains.python.psi.PyStatement;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.awt.event.MouseEvent;
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * @author traff
+ */
+public class PyExecuteFileLineMarkerProvider implements LineMarkerProvider {
+ @Nullable
+ @Override
+ public LineMarkerInfo getLineMarkerInfo(@NotNull PsiElement element) {
+ return null;
+ }
+
+ @Override
+ public void collectSlowLineMarkers(@NotNull List<PsiElement> elements, @NotNull Collection<LineMarkerInfo> result) {
+ for (PsiElement element : elements) {
+ if (isFirstCodeLine(element)) {
+ result.add(new LineMarkerInfo<PsiElement>(
+ element, element.getTextRange(), AllIcons.Actions.Execute, Pass.UPDATE_OVERRIDEN_MARKERS,
+ new Function<PsiElement, String>() {
+ @Override
+ public String fun(PsiElement e) {
+ return "Execute '" + e.getContainingFile().getName() + "'";
+ }
+ },
+ new GutterIconNavigationHandler<PsiElement>() {
+ @Override
+ public void navigate(MouseEvent e, PsiElement elt) {
+ executeCurrentScript(elt);
+ }
+ },
+ GutterIconRenderer.Alignment.RIGHT));
+ }
+ }
+ }
+
+ private static void executeCurrentScript(PsiElement elt) {
+ Editor editor = PsiUtilBase.findEditor(elt);
+ assert editor != null;
+
+ final ConfigurationContext context =
+ ConfigurationContext.getFromContext(DataManager.getInstance().getDataContext(editor.getComponent()));
+ PyRunCurrentFileAction.run(context);
+ }
+
+ private static boolean isFirstCodeLine(PsiElement element) {
+ return element instanceof PyStatement &&
+ element.getParent() instanceof PyFile &&
+ !isNothing(element) &&
+ nothingBefore(element);
+ }
+
+ private static boolean nothingBefore(PsiElement element) {
+ element = element.getPrevSibling();
+ while (element != null) {
+ if (!isNothing(element)) {
+ return false;
+ }
+ element = element.getPrevSibling();
+ }
+
+ return true;
+ }
+
+ private static boolean isNothing(PsiElement element) {
+ return (element instanceof PsiComment) || (element instanceof PyImportStatement) || (element instanceof PsiWhiteSpace);
+ }
+}
diff --git a/python/edu/src/com/jetbrains/python/edu/PyRunCurrentFileAction.java b/python/edu/src/com/jetbrains/python/edu/PyRunCurrentFileAction.java
new file mode 100644
index 000000000000..4d30fa29a3b3
--- /dev/null
+++ b/python/edu/src/com/jetbrains/python/edu/PyRunCurrentFileAction.java
@@ -0,0 +1,56 @@
+package com.jetbrains.python.edu;
+
+import com.intellij.execution.Location;
+import com.intellij.execution.RunManagerEx;
+import com.intellij.execution.RunnerAndConfigurationSettings;
+import com.intellij.execution.actions.ConfigurationContext;
+import com.intellij.execution.executors.DefaultRunExecutor;
+import com.intellij.execution.runners.ExecutionUtil;
+import com.intellij.icons.AllIcons;
+import com.intellij.openapi.actionSystem.AnAction;
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.actionSystem.Presentation;
+import com.jetbrains.python.PythonFileType;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author traff
+ */
+public class PyRunCurrentFileAction extends AnAction {
+ public PyRunCurrentFileAction() {
+ getTemplatePresentation().setIcon(AllIcons.Actions.Execute);
+ }
+
+ @Override
+ public void update(AnActionEvent e) {
+ Presentation presentation = e.getPresentation();
+ final ConfigurationContext context = ConfigurationContext.getFromContext(e.getDataContext());
+ Location location = context.getLocation();
+ if (location != null && location.getPsiElement().getContainingFile() != null && location.getPsiElement().getContainingFile().getFileType() == PythonFileType.INSTANCE) {
+ presentation.setEnabled(true);
+ presentation.setText("Run '" + location.getPsiElement().getContainingFile().getName() + "'");
+ }
+ }
+
+ @Override
+ public void actionPerformed(AnActionEvent e) {
+ final ConfigurationContext context = ConfigurationContext.getFromContext(e.getDataContext());
+
+ run(context);
+ }
+
+ public static void run(@NotNull ConfigurationContext context) {
+ RunnerAndConfigurationSettings configuration = context.findExisting();
+ final RunManagerEx runManager = (RunManagerEx)context.getRunManager();
+ if (configuration == null) {
+ configuration = context.getConfiguration();
+ if (configuration == null) {
+ return;
+ }
+ runManager.setTemporaryConfiguration(configuration);
+ }
+ runManager.setSelectedConfiguration(configuration);
+
+ ExecutionUtil.runConfiguration(configuration, DefaultRunExecutor.getRunExecutorInstance());
+ }
+}