EDU-285 Do not allow to run current file if no sdk selected
authorLiana Bakradze <liana.bakradze@jetbrains.com>
Mon, 24 Nov 2014 16:20:47 +0000 (19:20 +0300)
committerLiana Bakradze <liana.bakradze@jetbrains.com>
Mon, 24 Nov 2014 16:20:47 +0000 (19:20 +0300)
python/edu/learn-python/src/com/jetbrains/python/edu/StudyUtils.java
python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyCheckAction.java
python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyRunAction.java
python/edu/learn-python/src/com/jetbrains/python/edu/editor/StudyEditor.java

index 21881c629c7cfd0163b1bfb295ac81393948ee73..c84fbf81b7d8efbd9d4ef15264bffb39f9eec64e 100644 (file)
@@ -9,7 +9,9 @@ import com.intellij.openapi.editor.Document;
 import com.intellij.openapi.fileEditor.FileDocumentManager;
 import com.intellij.openapi.fileEditor.FileEditor;
 import com.intellij.openapi.fileEditor.FileEditorManager;
+import com.intellij.openapi.module.ModuleManager;
 import com.intellij.openapi.project.Project;
+import com.intellij.openapi.projectRoots.Sdk;
 import com.intellij.openapi.util.TextRange;
 import com.intellij.openapi.util.io.FileUtil;
 import com.intellij.openapi.vfs.VirtualFile;
@@ -19,6 +21,7 @@ import com.intellij.util.ui.UIUtil;
 import com.jetbrains.python.edu.course.*;
 import com.jetbrains.python.edu.editor.StudyEditor;
 import com.jetbrains.python.edu.ui.StudyToolWindowFactory;
+import com.jetbrains.python.sdk.PythonSdkType;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
@@ -185,4 +188,9 @@ public class StudyUtils {
     FileUtil.copy(new File(pathToResource, sourceName), resourceFile);
     return resourceFile;
   }
+
+  @Nullable
+  public static Sdk findPythonSdk(@NotNull final Project project) {
+    return PythonSdkType.findPythonSdk(ModuleManager.getInstance(project).getModules()[0]);
+  }
 }
index b5f4c003ffe8d4ec55d060f15425856de868d3cc..733514de75a96530cba404c1e5391d770d47119d 100644 (file)
@@ -12,8 +12,10 @@ import com.intellij.openapi.editor.Editor;
 import com.intellij.openapi.fileEditor.FileDocumentManager;
 import com.intellij.openapi.fileEditor.FileEditor;
 import com.intellij.openapi.fileEditor.FileEditorManager;
+import com.intellij.openapi.options.ShowSettingsUtil;
 import com.intellij.openapi.project.DumbAwareAction;
 import com.intellij.openapi.project.Project;
+import com.intellij.openapi.projectRoots.Sdk;
 import com.intellij.openapi.ui.MessageType;
 import com.intellij.openapi.ui.popup.Balloon;
 import com.intellij.openapi.ui.popup.BalloonBuilder;
@@ -33,6 +35,8 @@ import com.jetbrains.python.edu.editor.StudyEditor;
 import org.jetbrains.annotations.NotNull;
 
 import javax.swing.*;
+import javax.swing.event.HyperlinkEvent;
+import javax.swing.event.HyperlinkListener;
 import java.awt.*;
 import java.io.IOException;
 import java.util.Map;
@@ -41,7 +45,7 @@ public class StudyCheckAction extends DumbAwareAction {
 
   private static final Logger LOG = Logger.getInstance(StudyCheckAction.class.getName());
   private static final String ANSWERS_POSTFIX = "_answers.py";
-  public static final  String ACTION_ID = "CheckAction";
+  public static final String ACTION_ID = "CheckAction";
   public static final String SHORTCUT = "ctrl alt pressed ENTER";
 
 
@@ -108,9 +112,15 @@ public class StudyCheckAction extends DumbAwareAction {
             VirtualFile taskDir = studyState.getTaskDir();
             flushWindows(task, taskDir);
             StudyRunAction runAction = (StudyRunAction)ActionManager.getInstance().getAction(StudyRunAction.ACTION_ID);
-            if (runAction != null && taskFiles.size() == 1) {
-              runAction.run(project);
+            if (runAction == null) {
+              return;
+            }
+            Sdk sdk = StudyUtils.findPythonSdk(project);
+            if (sdk == null) {
+              createNoPythonInterpreterPopUp(project);
+              return;
             }
+            runAction.run(project, sdk);
             ApplicationManager.getApplication().invokeLater(new Runnable() {
               @Override
               public void run() {
@@ -157,6 +167,27 @@ public class StudyCheckAction extends DumbAwareAction {
     });
   }
 
+  private static void createNoPythonInterpreterPopUp(@NotNull final Project project) {
+    String text = "<html>No Python interpreter configured for the project<br><a href=\"\">Configure interpreter</a></html>";
+    BalloonBuilder balloonBuilder =
+      JBPopupFactory.getInstance().createHtmlTextBalloonBuilder(text, null, MessageType.WARNING.getPopupBackground(), new HyperlinkListener() {
+        @Override
+        public void hyperlinkUpdate(HyperlinkEvent event) {
+          if (event.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
+            ApplicationManager.getApplication().invokeLater(new Runnable() {
+              @Override
+              public void run() {
+                ShowSettingsUtil.getInstance().showSettingsDialog(project, "Project Interpreter");
+              }
+            });
+          }
+        }
+      });
+    balloonBuilder.setHideOnLinkClick(true);
+    final Balloon balloon = balloonBuilder.createBalloon();
+    showCheckPopUp(project, balloon);
+  }
+
   private static void navigateToFailedTaskWindow(@NotNull final StudyState studyState,
                                                  @NotNull final Task task,
                                                  @NotNull final VirtualFile taskDir,
@@ -261,6 +292,13 @@ public class StudyCheckAction extends DumbAwareAction {
     BalloonBuilder balloonBuilder =
       JBPopupFactory.getInstance().createHtmlTextBalloonBuilder(text, null, color, null);
     final Balloon balloon = balloonBuilder.createBalloon();
+    showCheckPopUp(project, balloon);
+  }
+
+  /**
+   * shows pop up in the center of "check task" button in study editor
+   */
+  private static void showCheckPopUp(@NotNull final Project project, @NotNull final Balloon balloon) {
     StudyEditor studyEditor = StudyEditor.getSelectedStudyEditor(project);
     assert studyEditor != null;
     JButton checkButton = studyEditor.getCheckButton();
index 71e95defdedcaa5d0a3b577b31519bfb2d24984a..44bd31b5ef566782851fa81432e06a610fae1328 100644 (file)
@@ -9,18 +9,18 @@ import com.intellij.openapi.actionSystem.AnActionEvent;
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.editor.Editor;
 import com.intellij.openapi.fileEditor.FileDocumentManager;
-import com.intellij.openapi.module.ModuleManager;
 import com.intellij.openapi.project.DumbAwareAction;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.projectRoots.Sdk;
 import com.intellij.openapi.util.Disposer;
 import com.intellij.openapi.vfs.VirtualFile;
-import com.jetbrains.python.sdk.PythonSdkType;
 import com.jetbrains.python.edu.StudyResourceManger;
 import com.jetbrains.python.edu.StudyTaskManager;
+import com.jetbrains.python.edu.StudyUtils;
 import com.jetbrains.python.edu.course.Task;
 import com.jetbrains.python.edu.course.TaskFile;
 import com.jetbrains.python.edu.editor.StudyEditor;
+import org.jetbrains.annotations.NotNull;
 
 import java.io.File;
 
@@ -28,7 +28,7 @@ public class StudyRunAction extends DumbAwareAction {
   private static final Logger LOG = Logger.getInstance(StudyRunAction.class.getName());
   public static final String ACTION_ID = "StudyRunAction";
 
-  public void run(Project project) {
+  public void run(@NotNull final Project project, @NotNull final Sdk sdk) {
     Editor selectedEditor = StudyEditor.getSelectedEditor(project);
     FileDocumentManager fileDocumentManager = FileDocumentManager.getInstance();
     assert selectedEditor != null;
@@ -37,9 +37,7 @@ public class StudyRunAction extends DumbAwareAction {
     if (openedFile != null && openedFile.getCanonicalPath() != null) {
       String filePath = openedFile.getCanonicalPath();
       GeneralCommandLine cmd = new GeneralCommandLine();
-      cmd.setWorkDirectory(openedFile.getParent().getCanonicalPath());
-      Sdk sdk = PythonSdkType.findPythonSdk(ModuleManager.getInstance(project).getModules()[0]);
-      if (sdk != null) {
+      cmd.withWorkDirectory(openedFile.getParent().getCanonicalPath());
         String pythonPath = sdk.getHomePath();
         if (pythonPath != null) {
           cmd.setExePath(pythonPath);
@@ -79,11 +77,18 @@ public class StudyRunAction extends DumbAwareAction {
             LOG.error(e);
           }
         }
-      }
     }
   }
 
-  public void actionPerformed(AnActionEvent e) {
-    run(e.getProject());
+  public void actionPerformed(@NotNull AnActionEvent e) {
+    Project project = e.getProject();
+    if (project == null) {
+      return;
+    }
+    Sdk sdk = StudyUtils.findPythonSdk(project);
+    if (sdk == null) {
+      return;
+    }
+    run(project, sdk);
   }
 }
index b497b5216c2690ac3923c25995153313f42957d0..14f932ede2f08d4fa4a020c17c1cbc0c38c129bd 100644 (file)
@@ -20,6 +20,7 @@ import com.intellij.openapi.fileEditor.impl.text.PsiAwareTextEditorImpl;
 import com.intellij.openapi.fileEditor.impl.text.TextEditorProvider;
 import com.intellij.openapi.keymap.KeymapUtil;
 import com.intellij.openapi.project.Project;
+import com.intellij.openapi.projectRoots.Sdk;
 import com.intellij.openapi.util.Disposer;
 import com.intellij.openapi.util.Key;
 import com.intellij.openapi.vfs.VirtualFile;
@@ -35,6 +36,7 @@ import com.intellij.util.ui.EmptyClipboardOwner;
 import com.intellij.util.ui.UIUtil;
 import com.jetbrains.python.edu.StudyDocumentListener;
 import com.jetbrains.python.edu.StudyTaskManager;
+import com.jetbrains.python.edu.StudyUtils;
 import com.jetbrains.python.edu.actions.*;
 import com.jetbrains.python.edu.course.Task;
 import com.jetbrains.python.edu.course.TaskFile;
@@ -209,23 +211,26 @@ public class StudyEditor implements TextEditor {
     myRefreshButton = addButton(taskActionsPanel, StudyRefreshTaskFileAction.ACTION_ID, AllIcons.Actions.Refresh, StudyRefreshTaskFileAction.SHORTCUT);
     JButton myShowHintButton = addButton(taskActionsPanel, StudyShowHintAction.ACTION_ID, StudyIcons.ShowHint, StudyShowHintAction.SHORTCUT);
     if (!taskFile.getTask().getUserTests().isEmpty()) {
-      JButton runButton = addButton(taskActionsPanel, StudyRunAction.ACTION_ID, AllIcons.General.Run, null);
-      runButton.addActionListener(new ActionListener() {
-        @Override
-        public void actionPerformed(ActionEvent e) {
-          StudyRunAction studyRunAction = (StudyRunAction)ActionManager.getInstance().getAction("StudyRunAction");
-          studyRunAction.run(myProject);
-        }
-      });
-      JButton watchInputButton = addButton(taskActionsPanel, "WatchInputAction", StudyIcons.WatchInput, null);
-      watchInputButton.addActionListener(new ActionListener() {
-        @Override
-        public void actionPerformed(ActionEvent e) {
-          StudyEditInputAction studyEditInputAction =
-            (StudyEditInputAction)ActionManager.getInstance().getAction("WatchInputAction");
-          studyEditInputAction.showInput(myProject);
-        }
-      });
+      final Sdk sdk = StudyUtils.findPythonSdk(myProject);
+      if (sdk != null) {
+        JButton runButton = addButton(taskActionsPanel, StudyRunAction.ACTION_ID, AllIcons.General.Run, null);
+        runButton.addActionListener(new ActionListener() {
+          @Override
+          public void actionPerformed(ActionEvent e) {
+            StudyRunAction studyRunAction = (StudyRunAction)ActionManager.getInstance().getAction("StudyRunAction");
+            studyRunAction.run(myProject, sdk);
+          }
+        });
+        JButton watchInputButton = addButton(taskActionsPanel, "WatchInputAction", StudyIcons.WatchInput, null);
+        watchInputButton.addActionListener(new ActionListener() {
+          @Override
+          public void actionPerformed(ActionEvent e) {
+            StudyEditInputAction studyEditInputAction =
+              (StudyEditInputAction)ActionManager.getInstance().getAction("WatchInputAction");
+            studyEditInputAction.showInput(myProject);
+          }
+        });
+      }
     }
     myCheckButton.addActionListener(new ActionListener() {
       @Override