EDU-273 Autocompletion for local *.py files in import
authorLiana Bakradze <liana.bakradze@jetbrains.com>
Tue, 25 Nov 2014 10:18:42 +0000 (13:18 +0300)
committerLiana Bakradze <liana.bakradze@jetbrains.com>
Tue, 25 Nov 2014 10:18:42 +0000 (13:18 +0300)
python/edu/learn-python/src/com/jetbrains/python/edu/StudyDirectoryProjectGenerator.java
python/edu/learn-python/src/com/jetbrains/python/edu/StudyUtils.java
python/edu/learn-python/src/com/jetbrains/python/edu/course/Course.java
python/edu/learn-python/src/com/jetbrains/python/edu/course/Lesson.java
python/edu/learn-python/src/com/jetbrains/python/edu/course/Task.java

index 90a4b74521def806138b1ce3373f46864b9cf91b..f6435e6b2a9adf457c4e0ee47b5c81b68cec51a4 100644 (file)
@@ -164,7 +164,7 @@ public class StudyDirectoryProjectGenerator extends PythonProjectGenerator imple
       Gson gson = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES).create();
       final Course course = gson.fromJson(reader, Course.class);
       course.init(false);
-      course.create(baseDir, new File(mySelectedCourseFile.getParent()));
+      course.create(baseDir, new File(mySelectedCourseFile.getParent()), project);
       course.setResourcePath(mySelectedCourseFile.getAbsolutePath());
       VirtualFileManager.getInstance().refreshWithoutFileWatcher(true);
       StudyTaskManager.getInstance(project).setCourse(course);
index c84fbf81b7d8efbd9d4ef15264bffb39f9eec64e..4add8f4ce41431553809a227b7fbf532591cec4e 100644 (file)
@@ -1,6 +1,7 @@
 package com.jetbrains.python.edu;
 
 import com.intellij.ide.SaveAndSyncHandlerImpl;
+import com.intellij.ide.projectView.actions.MarkRootActionBase;
 import com.intellij.openapi.actionSystem.AnActionEvent;
 import com.intellij.openapi.actionSystem.Presentation;
 import com.intellij.openapi.application.ApplicationManager;
@@ -9,9 +10,14 @@ 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.Module;
 import com.intellij.openapi.module.ModuleManager;
+import com.intellij.openapi.module.ModuleUtilCore;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.projectRoots.Sdk;
+import com.intellij.openapi.roots.ContentEntry;
+import com.intellij.openapi.roots.ModifiableRootModel;
+import com.intellij.openapi.roots.ModuleRootManager;
 import com.intellij.openapi.util.TextRange;
 import com.intellij.openapi.util.io.FileUtil;
 import com.intellij.openapi.vfs.VirtualFile;
@@ -30,6 +36,7 @@ import java.util.Collection;
 
 public class StudyUtils {
   private static final Logger LOG = Logger.getInstance(StudyUtils.class.getName());
+
   public static void closeSilently(Closeable stream) {
     if (stream != null) {
       try {
@@ -58,7 +65,7 @@ public class StudyUtils {
   @Nullable
   public static String getFileText(String parentDir, String fileName, boolean wrapHTML) {
 
-    File inputFile = parentDir !=null ? new File(parentDir, fileName) : new File(fileName);
+    File inputFile = parentDir != null ? new File(parentDir, fileName) : new File(fileName);
     if (!inputFile.exists()) return null;
     StringBuilder taskText = new StringBuilder();
     BufferedReader reader = null;
@@ -99,12 +106,14 @@ public class StudyUtils {
   }
 
   public static void updateStudyToolWindow(Project project) {
-    ToolWindowManager.getInstance(project).getToolWindow(StudyToolWindowFactory.STUDY_TOOL_WINDOW).getContentManager().removeAllContents(false);
-    StudyToolWindowFactory factory =  new StudyToolWindowFactory();
-    factory.createToolWindowContent(project, ToolWindowManager.getInstance(project).getToolWindow(StudyToolWindowFactory.STUDY_TOOL_WINDOW));
+    ToolWindowManager.getInstance(project).getToolWindow(StudyToolWindowFactory.STUDY_TOOL_WINDOW).getContentManager()
+      .removeAllContents(false);
+    StudyToolWindowFactory factory = new StudyToolWindowFactory();
+    factory
+      .createToolWindowContent(project, ToolWindowManager.getInstance(project).getToolWindow(StudyToolWindowFactory.STUDY_TOOL_WINDOW));
   }
 
-  public  static void synchronize() {
+  public static void synchronize() {
     FileDocumentManager.getInstance().saveAllDocuments();
     SaveAndSyncHandlerImpl.refreshOpenFiles();
     VirtualFileManager.getInstance().refreshWithoutFileWatcher(true);
@@ -156,7 +165,7 @@ public class StudyUtils {
         });
       }
       catch (IOException e) {
-       LOG.error(e);
+        LOG.error(e);
       }
       finally {
         closeSilently(printWriter);
@@ -193,4 +202,26 @@ public class StudyUtils {
   public static Sdk findPythonSdk(@NotNull final Project project) {
     return PythonSdkType.findPythonSdk(ModuleManager.getInstance(project).getModules()[0]);
   }
+
+  public static void markDirAsSourceRoot(@NotNull final VirtualFile dir, @NotNull final Project project) {
+    final Module module = ModuleUtilCore.findModuleForFile(dir, project);
+    if (module == null) {
+      LOG.info("Module for " + dir.getPath() + " was not found");
+      return;
+    }
+    final ModifiableRootModel model = ModuleRootManager.getInstance(module).getModifiableModel();
+    ContentEntry entry = MarkRootActionBase.findContentEntry(model, dir);
+    if (entry == null) {
+      LOG.info("Content entry for " + dir.getPath() + " was not found");
+      return;
+    }
+    entry.addSourceFolder(dir, false);
+    ApplicationManager.getApplication().runWriteAction(new Runnable() {
+      @Override
+      public void run() {
+        model.commit();
+        module.getProject().save();
+      }
+    });
+  }
 }
index b5c0f8992b8417f9df4dd5352ab57bd105e3df13..a16b3405f37524dfb7b8d6327715e15676f5f2f1 100644 (file)
@@ -2,6 +2,7 @@ package com.jetbrains.python.edu.course;
 
 import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.project.Project;
 import com.intellij.openapi.util.io.FileUtil;
 import com.intellij.openapi.vfs.VirtualFile;
 import org.jetbrains.annotations.NotNull;
@@ -48,7 +49,8 @@ public class Course {
    * @param baseDir      project directory
    * @param resourceRoot directory where original course is stored
    */
-  public void create(@NotNull final VirtualFile baseDir, @NotNull final File resourceRoot) {
+  public void create(@NotNull final VirtualFile baseDir, @NotNull final File resourceRoot,
+                     @NotNull final Project project) {
     ApplicationManager.getApplication().invokeLater(
       new Runnable() {
         @Override
@@ -60,16 +62,16 @@ public class Course {
                 for (int i = 0; i < lessons.size(); i++) {
                   Lesson lesson = lessons.get(i);
                   lesson.setIndex(i);
-                  lesson.create(baseDir, resourceRoot);
+                  lesson.create(baseDir, resourceRoot, project);
                 }
                 baseDir.createChildDirectory(this, SANDBOX_DIR);
                 File[] files = resourceRoot.listFiles(new FilenameFilter() {
                   @Override
                   public boolean accept(File dir, String name) {
-                   return !name.contains(Lesson.LESSON_DIR) && !name.equals("course.json") && !name.equals("hints");
+                    return !name.contains(Lesson.LESSON_DIR) && !name.equals("course.json") && !name.equals("hints");
                   }
                 });
-                for (File file: files) {
+                for (File file : files) {
                   FileUtil.copy(file, new File(baseDir.getPath(), file.getName()));
                 }
               }
index 3879d519957ed9fc626e3868a0364788de21f343..b4a3286dfd9416e074dc91ea2b9e5922ba764234 100644 (file)
@@ -1,5 +1,6 @@
 package com.jetbrains.python.edu.course;
 
+import com.intellij.openapi.project.Project;
 import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.util.xmlb.annotations.Transient;
 import org.jetbrains.annotations.NotNull;
@@ -9,7 +10,7 @@ import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
 
-public class Lesson implements Stateful{
+public class Lesson implements Stateful {
   public String name;
   public List<Task> taskList = new ArrayList<Task>();
   private Course myCourse = null;
@@ -59,13 +60,14 @@ public class Lesson implements Stateful{
    * @param resourceRoot directory where original lesson stored
    * @throws java.io.IOException
    */
-  public void create(@NotNull final VirtualFile courseDir, @NotNull final File resourceRoot) throws IOException {
+  public void create(@NotNull final VirtualFile courseDir, @NotNull final File resourceRoot,
+                     @NotNull final Project project) throws IOException {
     String lessonDirName = LESSON_DIR + Integer.toString(myIndex + 1);
     VirtualFile lessonDir = courseDir.createChildDirectory(this, lessonDirName);
     for (int i = 0; i < taskList.size(); i++) {
       Task task = taskList.get(i);
       task.setIndex(i);
-      task.create(lessonDir, new File(resourceRoot, lessonDir.getName()));
+      task.create(lessonDir, new File(resourceRoot, lessonDir.getName()), project);
     }
   }
 
index 2323412f4374c1a61f3ce6ba2a9b3129bd6eefd0..26def69d14c5f6ee44e879f4a1d1897cc3055c18 100644 (file)
@@ -4,9 +4,9 @@ import com.intellij.openapi.project.Project;
 import com.intellij.openapi.util.io.FileUtil;
 import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.util.xmlb.annotations.Transient;
+import com.jetbrains.python.edu.StudyUtils;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
-import com.jetbrains.python.edu.StudyUtils;
 
 import java.io.File;
 import java.io.IOException;
@@ -18,7 +18,7 @@ import java.util.Map;
 /**
  * Implementation of task which contains task files, tests, input file for tests
  */
-public class Task implements Stateful{
+public class Task implements Stateful {
   public static final String TASK_DIR = "task";
   private static final String ourTestFile = "tests.py";
   public String name;
@@ -85,8 +85,10 @@ public class Task implements Stateful{
    * @param resourceRoot directory where original task file stored
    * @throws java.io.IOException
    */
-  public void create(@NotNull final VirtualFile lessonDir, @NotNull final File resourceRoot) throws IOException {
+  public void create(@NotNull final VirtualFile lessonDir, @NotNull final File resourceRoot,
+                     @NotNull final Project project) throws IOException {
     VirtualFile taskDir = lessonDir.createChildDirectory(this, TASK_DIR + Integer.toString(myIndex + 1));
+    StudyUtils.markDirAsSourceRoot(taskDir, project);
     File newResourceRoot = new File(resourceRoot, taskDir.getName());
     int i = 0;
     for (Map.Entry<String, TaskFile> taskFile : taskFiles.entrySet()) {
@@ -197,5 +199,4 @@ public class Task implements Stateful{
     }
     return null;
   }
-
 }