added idea support
authorliana.bakradze <liana.bakradze@jetbrains.com>
Mon, 23 Mar 2015 09:46:08 +0000 (12:46 +0300)
committerliana.bakradze <liana.bakradze@jetbrains.com>
Mon, 23 Mar 2015 09:46:08 +0000 (12:46 +0300)
18 files changed:
python/edu/course-creator-intellij-py/course-creator-intellij-py.iml [new file with mode: 0644]
python/edu/course-creator-intellij-py/resources/META-INF/plugin.xml [new file with mode: 0644]
python/edu/course-creator-intellij-py/src/PyCCEduProjectTemplate.java [new file with mode: 0644]
python/edu/course-creator-python/src/com/jetbrains/edu/coursecreator/PyCCProjectGenerator.java
python/edu/interactive-learning-intellij-py/interactive-learning-intellij-py.iml [new file with mode: 0644]
python/edu/interactive-learning-intellij-py/resources/META-INF/plugin.xml [new file with mode: 0644]
python/edu/interactive-learning-intellij-py/resources/fileTemplates/internal/test_helper.py.ft [new file with mode: 0644]
python/edu/interactive-learning-intellij-py/src/PyEduProjectTemplate.java [new file with mode: 0644]
python/edu/interactive-learning-python/resources/META-INF/plugin.xml
python/edu/interactive-learning-python/src/com/jetbrains/edu/learning/PyStudyDirectoryProjectGenerator.java
python/educational/course-creator/src/com/jetbrains/edu/coursecreator/ui/CCNewProjectPanel.java
python/educational/interactive-learning-intellij/interactive-learning-intellij.iml [new file with mode: 0644]
python/educational/interactive-learning-intellij/resources/META-INF/plugin.xml [new file with mode: 0644]
python/educational/interactive-learning-intellij/src/EduProjectTemplate.java [new file with mode: 0644]
python/educational/interactive-learning-intellij/src/EduProjectTemplateFactory.java [new file with mode: 0644]
python/educational/interactive-learning/src/com/jetbrains/edu/learning/projectView/StudyTreeStructureProvider.java
python/educational/interactive-learning/src/com/jetbrains/edu/learning/ui/StudyNewProjectPanel.form
python/educational/interactive-learning/src/com/jetbrains/edu/learning/ui/StudyNewProjectPanel.java

diff --git a/python/edu/course-creator-intellij-py/course-creator-intellij-py.iml b/python/edu/course-creator-intellij-py/course-creator-intellij-py.iml
new file mode 100644 (file)
index 0000000..fff5053
--- /dev/null
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="JAVA_MODULE" version="4">
+  <component name="NewModuleRootManager" inherit-compiler-output="true">
+    <exclude-output />
+    <content url="file://$MODULE_DIR$">
+      <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/resources" type="java-resource" />
+    </content>
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+    <orderEntry type="module" module-name="interactive-learning-intellij" />
+    <orderEntry type="module" module-name="lang-api" />
+    <orderEntry type="module" module-name="python-community-plugin" />
+    <orderEntry type="module" module-name="course-creator" />
+    <orderEntry type="module" module-name="course-creator-python" />
+    <orderEntry type="module" module-name="main" />
+    <orderEntry type="module" module-name="python-community" />
+    <orderEntry type="module" module-name="openapi" />
+    <orderEntry type="module" module-name="interactive-learning-intellij-py" />
+    <orderEntry type="module" module-name="interactive-learning" />
+  </component>
+</module>
\ No newline at end of file
diff --git a/python/edu/course-creator-intellij-py/resources/META-INF/plugin.xml b/python/edu/course-creator-intellij-py/resources/META-INF/plugin.xml
new file mode 100644 (file)
index 0000000..ec3596c
--- /dev/null
@@ -0,0 +1,38 @@
+<!--suppress XmlUnboundNsPrefix -->
+<idea-plugin version="2">
+  <id>com.jetbrains.edu.coursecreator.intellij.python</id>
+  <name>Plugin for Intellij IDEA for creating python courses</name>
+  <version>2.0</version>
+
+  <description><![CDATA[
+      Educational plugin core for students. 
+      ]]></description>
+
+  <change-notes><![CDATA[
+
+      ]]>
+  </change-notes>
+
+  <depends>com.intellij.modules.lang</depends>
+  <depends>com.intellij.modules.python</depends>
+  <depends>com.jetbrains.edu.interactivelearning.intellij</depends>
+  <depends>com.jetbrains.edu.coursecreator</depends>
+  <depends>com.jetbrains.edu.coursecreator.python</depends>
+
+  <project-components>
+
+  </project-components>
+
+  <application-components>
+
+  </application-components>
+
+  <actions>
+
+  </actions>
+
+  <extensions defaultExtensionNs="com.jetbrains.edu.interactivelearning.intellij">
+    <EduProjectTemplate implementation="PyCCEduProjectTemplate"/>
+  </extensions>
+
+</idea-plugin>
\ No newline at end of file
diff --git a/python/edu/course-creator-intellij-py/src/PyCCEduProjectTemplate.java b/python/edu/course-creator-intellij-py/src/PyCCEduProjectTemplate.java
new file mode 100644 (file)
index 0000000..d725173
--- /dev/null
@@ -0,0 +1,92 @@
+import com.intellij.ide.util.projectWizard.AbstractModuleBuilder;
+import com.intellij.ide.util.projectWizard.WizardInputField;
+import com.intellij.openapi.module.ModifiableModuleModel;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.options.ConfigurationException;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.projectRoots.Sdk;
+import com.intellij.openapi.roots.ModifiableRootModel;
+import com.intellij.openapi.startup.StartupManager;
+import com.intellij.openapi.ui.ValidationInfo;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.jetbrains.edu.coursecreator.PyCCProjectGenerator;
+import com.jetbrains.edu.coursecreator.ui.CCNewProjectPanel;
+import com.jetbrains.python.facet.PythonSdkComboBox;
+import com.jetbrains.python.module.PythonModuleBuilder;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import java.util.ArrayList;
+import java.util.List;
+
+public class PyCCEduProjectTemplate extends EduProjectTemplate {
+
+  @NotNull
+  @Override
+  public String getName() {
+    return "Python Course Creation";
+  }
+
+  @Override
+  public String getDescription() {
+    return null;
+  }
+
+  @Override
+  public Icon getIcon() {
+    return null;
+  }
+
+  @NotNull
+  @Override
+  public AbstractModuleBuilder createModuleBuilder() {
+    return new PythonEduModuleBuilder() ;
+  }
+
+  @Override
+  public ValidationInfo validateSettings() {
+    return null;
+  }
+
+  private static class PythonEduModuleBuilder extends PythonModuleBuilder {
+    @Override
+    public void setupRootModel(ModifiableRootModel rootModel) throws ConfigurationException {
+      super.setupRootModel(rootModel);
+      Sdk sdk = mySdkComboBox.getSelectedSdk();
+      if (sdk != null) {
+        rootModel.setSdk(sdk);
+      }
+    }
+
+    final PythonSdkComboBox mySdkComboBox = new PythonSdkComboBox();
+    final CCNewProjectPanel panel = new CCNewProjectPanel();
+
+
+    @Override
+    protected List<WizardInputField> getAdditionalFields() {
+      List<WizardInputField> wizardInputFields = new ArrayList<WizardInputField>();
+      wizardInputFields.add(createWizardInputField("Edu.CCProjectSdk", "Python Interpreter:", mySdkComboBox));
+      wizardInputFields.add(createWizardInputField("Edu.Author", "Author:", panel.getAuthorField()));
+      wizardInputFields.add(createWizardInputField("Edu.Name", "Name:", panel.getNameField()));
+      wizardInputFields.add(createWizardInputField("Edu.Description", "Description:", panel.getDescriptionField()));
+      return wizardInputFields;
+    }
+
+    @Nullable
+    @Override
+    public Module commitModule(@NotNull final Project project, @Nullable ModifiableModuleModel model) {
+      Module module = super.commitModule(project, model);
+      if (module != null) {
+        final VirtualFile baseDir = project.getBaseDir();
+        StartupManager.getInstance(project).runWhenProjectIsInitialized(new Runnable() {
+          @Override
+          public void run() {
+            PyCCProjectGenerator.generateProject(project, baseDir, panel.getName(), panel.getAuthor(), panel.getDescription());
+          }
+        });
+      }
+      return module;
+    }
+  }
+}
index eb0bed483c44cd10326137624b366398f551818b..e4ea96ad67dee034a648522e0ec7ba3a96f772ba 100644 (file)
@@ -58,7 +58,7 @@ public class PyCCProjectGenerator extends PythonProjectGenerator implements Dire
                     mySettingsPanel.getAuthor(), mySettingsPanel.getDescription());
   }
 
-  private static void generateProject(@NotNull final Project project, @NotNull final VirtualFile baseDir,
+  public static void generateProject(@NotNull final Project project, @NotNull final VirtualFile baseDir,
                                      @NotNull final String name, @NotNull final String author,
                                      @NotNull final String description) {
 
diff --git a/python/edu/interactive-learning-intellij-py/interactive-learning-intellij-py.iml b/python/edu/interactive-learning-intellij-py/interactive-learning-intellij-py.iml
new file mode 100644 (file)
index 0000000..c22169c
--- /dev/null
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="JAVA_MODULE" version="4">
+  <component name="NewModuleRootManager" inherit-compiler-output="true">
+    <exclude-output />
+    <content url="file://$MODULE_DIR$">
+      <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/resources" type="java-resource" />
+    </content>
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+    <orderEntry type="module" module-name="util" />
+    <orderEntry type="module" module-name="lang-api" />
+    <orderEntry type="module" module-name="python-community-plugin" />
+    <orderEntry type="module" module-name="interactive-learning" />
+    <orderEntry type="module" module-name="lang-impl" />
+    <orderEntry type="module" module-name="interactive-learning-intellij" />
+    <orderEntry type="module" module-name="main" />
+    <orderEntry type="module" module-name="python-community" />
+    <orderEntry type="module" module-name="openapi" />
+    <orderEntry type="module" module-name="interactive-learning-python" />
+  </component>
+</module>
\ No newline at end of file
diff --git a/python/edu/interactive-learning-intellij-py/resources/META-INF/plugin.xml b/python/edu/interactive-learning-intellij-py/resources/META-INF/plugin.xml
new file mode 100644 (file)
index 0000000..10c8e18
--- /dev/null
@@ -0,0 +1,38 @@
+<!--suppress XmlUnboundNsPrefix -->
+<idea-plugin version="2">
+  <id>com.jetbrains.edu.interactivelearning.intellij.python</id>
+  <name>Educational plugin for Intellij Python</name>
+  <version>2.0</version>
+
+  <description><![CDATA[
+      Educational plugin core for students. 
+      ]]></description>
+
+  <change-notes><![CDATA[
+
+      ]]>
+  </change-notes>
+
+  <depends>com.intellij.modules.lang</depends>
+  <depends>com.intellij.modules.python</depends>
+  <depends>com.jetbrains.edu.interactivelearning</depends>
+  <depends>com.jetbrains.python.edu.interactivelearning.python</depends>
+  <depends>com.jetbrains.edu.interactivelearning.intellij</depends>
+
+  <project-components>
+
+  </project-components>
+
+  <application-components>
+
+  </application-components>
+
+  <actions>
+
+  </actions>
+
+  <extensions defaultExtensionNs="com.jetbrains.edu.interactivelearning.intellij">
+    <EduProjectTemplate implementation="PyEduProjectTemplate"/>
+  </extensions>
+
+</idea-plugin>
\ No newline at end of file
diff --git a/python/edu/interactive-learning-intellij-py/resources/fileTemplates/internal/test_helper.py.ft b/python/edu/interactive-learning-intellij-py/resources/fileTemplates/internal/test_helper.py.ft
new file mode 100644 (file)
index 0000000..78545a2
--- /dev/null
@@ -0,0 +1,190 @@
+import sys
+
+
+def get_file_text(path):
+    """ Returns file text by path"""
+    file_io = open(path, "r")
+    text = file_io.read()
+    file_io.close()
+    return text
+
+
+def get_file_output(encoding="utf-8", path=sys.argv[-1]):
+    """
+    Returns answer file output
+    :param encoding: to decode output in python3
+    :param path: path of file to execute
+    :return: list of strings
+    """
+    import subprocess
+
+    proc = subprocess.Popen([sys.executable, path], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+    return list(map(lambda x: str(x.decode(encoding)), proc.communicate()[0].splitlines()))
+
+
+def test_file_importable():
+    """ Tests there is no obvious syntax errors"""
+    path = sys.argv[-1]
+    if not path.endswith(".py"):
+        import os
+
+        parent = os.path.abspath(os.path.join(path, os.pardir))
+        python_files = [f for f in os.listdir(parent) if os.path.isfile(os.path.join(parent, f)) and f.endswith(".py")]
+        for python_file in python_files:
+            if python_file == "tests.py": continue
+            check_importable_path(os.path.join(parent, python_file))
+        return
+    check_importable_path(path)
+
+
+def check_importable_path(path):
+    """ Checks that file is importable.
+        Reports failure otherwise.
+    """
+    try:
+        import_file(path)
+    except:
+        failed("The file contains syntax errors", test_file_importable.__name__)
+        return
+    passed(test_file_importable.__name__)
+
+
+def import_file(path):
+    """ Returns imported file """
+    if sys.version_info[0] == 2 or sys.version_info[1] < 3:
+        import imp
+
+        return imp.load_source("tmp", path)
+    elif sys.version_info[0] == 3:
+        import importlib.machinery
+
+        return importlib.machinery.SourceFileLoader("tmp", path).load_module("tmp")
+
+
+def import_task_file():
+    """ Returns imported file.
+        Imports file from which check action was run
+    """
+    path = sys.argv[-1]
+    return import_file(path)
+
+
+def test_is_not_empty():
+    """
+        Checks that file is not empty
+    """
+    path = sys.argv[-1]
+    file_text = get_file_text(path)
+
+    if len(file_text) > 0:
+        passed()
+    else:
+        failed("The file is empty. Please, reload the task and try again.")
+
+
+def test_is_initial_text(error_text="You should modify the file"):
+    """
+        Checks that file was modified
+    """
+    path = sys.argv[-1]
+    text = get_initial_text(path)
+    file_text = get_file_text(path)
+
+    if file_text.strip() == text:
+        failed(error_text)
+    else:
+        passed()
+
+
+def get_initial_text(path):
+    """
+        Returns the initial task text
+    """
+    course_lib = sys.argv[-2]
+
+    import os
+    # path format is "project_root/lessonX/taskY/file.py"
+    task_index = path.rfind(os.sep, 0, path.rfind(os.sep))
+    index = path.rfind(os.sep, 0, task_index)
+    relative_path = path[index + 1:]
+    initial_file_path = os.path.join(course_lib, relative_path)
+    return get_file_text(initial_file_path)
+
+
+def test_text_equals(text, error_text):
+    """
+        Checks that answer equals text.
+    """
+    path = sys.argv[-1]
+    file_text = get_file_text(path)
+
+    if file_text.strip() == text:
+        passed()
+    else:
+        failed(error_text)
+
+
+def test_answer_placeholders_text_deleted(error_text="Don't just delete task text"):
+    """
+        Checks that all answer placeholders are not empty
+    """
+    windows = get_answer_placeholders()
+
+    for window in windows:
+        if len(window) == 0:
+            failed(error_text)
+            return
+    passed()
+
+
+def failed(message="Please, reload the task and try again.", name=None):
+    """ Reports failure """
+    if not name:
+        name = sys._getframe().f_back.f_code.co_name
+    print("#educational_plugin " + name + " FAILED + " + message)
+
+
+def passed(name=None):
+    """ Reports success """
+    if not name:
+        name = sys._getframe().f_back.f_code.co_name
+    print("#educational_plugin " + name + " test OK")
+
+
+def get_answer_placeholders():
+    """
+        Returns all answer placeholders text
+    """
+    prefix = "#educational_plugin_window = "
+    path = sys.argv[-1]
+    import os
+
+    file_name_without_extension = os.path.splitext(path)[0]
+    windows_path = file_name_without_extension + "_windows"
+    windows = []
+    f = open(windows_path, "r")
+    window_text = ""
+    first = True
+    for line in f.readlines():
+        if line.startswith(prefix):
+            if not first:
+                windows.append(window_text.strip())
+            else:
+                first = False
+            window_text = line[len(prefix):]
+        else:
+            window_text += line
+
+    if window_text:
+        windows.append(window_text.strip())
+
+    f.close()
+    return windows
+
+
+def run_common_tests(error_text="Please, reload file and try again"):
+    test_is_initial_text()
+    test_is_not_empty()
+    test_answer_placeholders_text_deleted()
+    test_file_importable()
+
diff --git a/python/edu/interactive-learning-intellij-py/src/PyEduProjectTemplate.java b/python/edu/interactive-learning-intellij-py/src/PyEduProjectTemplate.java
new file mode 100644 (file)
index 0000000..ea8e39b
--- /dev/null
@@ -0,0 +1,112 @@
+import com.intellij.ide.fileTemplates.FileTemplate;
+import com.intellij.ide.fileTemplates.FileTemplateManager;
+import com.intellij.ide.fileTemplates.FileTemplateUtil;
+import com.intellij.ide.util.projectWizard.AbstractModuleBuilder;
+import com.intellij.ide.util.projectWizard.WizardInputField;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.module.ModifiableModuleModel;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.options.ConfigurationException;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.projectRoots.Sdk;
+import com.intellij.openapi.roots.ModifiableRootModel;
+import com.intellij.openapi.startup.StartupManager;
+import com.intellij.openapi.ui.ValidationInfo;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.PsiDirectory;
+import com.intellij.psi.PsiManager;
+import com.jetbrains.edu.learning.courseGeneration.StudyProjectGenerator;
+import com.jetbrains.edu.learning.ui.StudyNewProjectPanel;
+import com.jetbrains.python.facet.PythonSdkComboBox;
+import com.jetbrains.python.module.PythonModuleBuilder;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import java.util.ArrayList;
+import java.util.List;
+
+public class PyEduProjectTemplate extends EduProjectTemplate {
+  private static final Logger LOG = Logger.getInstance(PyEduProjectTemplate.class);
+
+  @NotNull
+  @Override
+  public String getName() {
+    return "Python";
+  }
+
+  @Nullable
+  @Override
+  public String getDescription() {
+    return null;
+  }
+
+  @Override
+  public Icon getIcon() {
+    return null;
+  }
+
+  @NotNull
+  @Override
+  public AbstractModuleBuilder createModuleBuilder() {
+    return new PythonEduModuleBuilder();
+  }
+
+  @Nullable
+  @Override
+  public ValidationInfo validateSettings() {
+    return null;
+  }
+
+  private static class PythonEduModuleBuilder extends PythonModuleBuilder {
+
+    final StudyProjectGenerator studyProjectGenerator = new StudyProjectGenerator();
+    final PythonSdkComboBox mySdkComboBox = new PythonSdkComboBox();
+
+    @Override
+    public void setupRootModel(ModifiableRootModel rootModel) throws ConfigurationException {
+      super.setupRootModel(rootModel);
+      Sdk sdk = mySdkComboBox.getSelectedSdk();
+      if (sdk != null) {
+        rootModel.setSdk(sdk);
+      }
+    }
+
+    @Override
+    protected List<WizardInputField> getAdditionalFields() {
+      final StudyNewProjectPanel panel = new StudyNewProjectPanel(studyProjectGenerator);
+      List<WizardInputField> wizardInputFields = new ArrayList<WizardInputField>();
+      wizardInputFields.add(createWizardInputField("Edu.ProjectSdk", "Python Interpreter:", mySdkComboBox));
+      wizardInputFields.add(createWizardInputField("Edu.Courses", "Courses:", panel.getCoursesComboBox()));
+      wizardInputFields.add(createWizardInputField("Edu.InfoPanel", "", panel.getInfoPanel()));
+      return wizardInputFields;
+    }
+
+    @Nullable
+    @Override
+    public Module commitModule(@NotNull final Project project, @Nullable ModifiableModuleModel model) {
+      Module module = super.commitModule(project, model);
+      if (module != null) {
+        final VirtualFile baseDir = project.getBaseDir();
+        studyProjectGenerator.generateProject(project, baseDir);
+        final FileTemplate template = FileTemplateManager.getInstance(project).getInternalTemplate("test_helper.py");
+
+        StartupManager.getInstance(project).runWhenProjectIsInitialized(new Runnable() {
+          @Override
+          public void run() {
+            final PsiDirectory projectDir = PsiManager.getInstance(project).findDirectory(baseDir);
+            if (projectDir != null) {
+              try {
+                FileTemplateUtil.createFromTemplate(template, "test_helper.py", null, projectDir);
+              }
+              catch (Exception e) {
+                LOG.error("Failed to create test_helper", e);
+              }
+            }
+          }
+        });
+      }
+      return module;
+    }
+  }
+}
\ No newline at end of file
index a9eca088e5f120404b7c943c3a2c453e3edaf618..82173a428f0910f63a1766194d9c2d6a24ff5fb4 100644 (file)
       ]]>
   </change-notes>
 
-  <!--depends>com.intellij.modules.python</depends-->
-
-  <!-- please see http://confluence.jetbrains.net/display/IDEADEV/Plugin+Compatibility+with+IntelliJ+Platform+Products
-       on how to target different products -->
-
   <depends>com.intellij.modules.lang</depends>
   <depends>com.intellij.modules.python</depends>
   <depends>com.jetbrains.edu.interactivelearning</depends>
index 1f3ffca7e256cd86a0bb86bcda591ee628e4faef..d49e373e5342b7ca31669a840b2fd956b1fe3097 100644 (file)
@@ -108,4 +108,8 @@ public class PyStudyDirectoryProjectGenerator extends PythonProjectGenerator imp
   public void setSelectedCourse(CourseInfo course) {
     myGenerator.setSelectedCourse(course);
   }
+
+  public StudyProjectGenerator getGenerator() {
+    return myGenerator;
+  }
 }
index 116104929d680c428aa6f5e33b0043abbf190a67..b5800fcf96d07b159a29170704c4df3be4e9dc3b 100644 (file)
@@ -68,4 +68,16 @@ public class CCNewProjectPanel {
       }
     }
   }
+
+  public JTextField getAuthorField() {
+    return myAuthorField;
+  }
+
+  public JTextArea getDescriptionField() {
+    return myDescription;
+  }
+
+  public JTextField getNameField() {
+    return myName;
+  }
 }
diff --git a/python/educational/interactive-learning-intellij/interactive-learning-intellij.iml b/python/educational/interactive-learning-intellij/interactive-learning-intellij.iml
new file mode 100644 (file)
index 0000000..82edead
--- /dev/null
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="JAVA_MODULE" version="4">
+  <component name="NewModuleRootManager" inherit-compiler-output="true">
+    <exclude-output />
+    <content url="file://$MODULE_DIR$">
+      <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/pluginResources" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/pluginResources/fileTemplates/internal" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/pluginResources/fileTemplates/j2ee" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/resources" type="java-resource" />
+    </content>
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+    <orderEntry type="module" module-name="lang-api" />
+    <orderEntry type="module" module-name="platform-impl" />
+  </component>
+</module>
\ No newline at end of file
diff --git a/python/educational/interactive-learning-intellij/resources/META-INF/plugin.xml b/python/educational/interactive-learning-intellij/resources/META-INF/plugin.xml
new file mode 100644 (file)
index 0000000..402bff2
--- /dev/null
@@ -0,0 +1,44 @@
+<idea-plugin version="2">
+  <id>com.jetbrains.edu.interactivelearning.intellij</id>
+  <name>Educational plugin for Intellij</name>
+  <version>2.0</version>
+
+  <description><![CDATA[
+      Educational plugin core for students. 
+      ]]></description>
+
+  <change-notes><![CDATA[
+
+      ]]>
+  </change-notes>
+
+  <depends>com.intellij.modules.python</depends>
+  <depends>com.jetbrains.edu.interactivelearning</depends>
+  <depends>com.jetbrains.python.edu.interactivelearning.python</depends>
+
+  <!-- please see http://confluence.jetbrains.net/display/IDEADEV/Plugin+Compatibility+with+IntelliJ+Platform+Products
+       on how to target different products -->
+
+  <depends>com.intellij.modules.lang</depends>
+
+  <project-components>
+
+  </project-components>
+
+  <application-components>
+
+  </application-components>
+
+  <actions>
+
+  </actions>
+
+  <extensions defaultExtensionNs="com.intellij">
+    <projectTemplatesFactory implementation="EduProjectTemplateFactory"/>
+  </extensions>
+
+  <extensionPoints>
+    <extensionPoint name="EduProjectTemplate" interface="EduProjectTemplate"/>
+  </extensionPoints>
+
+</idea-plugin>
\ No newline at end of file
diff --git a/python/educational/interactive-learning-intellij/src/EduProjectTemplate.java b/python/educational/interactive-learning-intellij/src/EduProjectTemplate.java
new file mode 100644 (file)
index 0000000..56823c7
--- /dev/null
@@ -0,0 +1,28 @@
+import com.intellij.ide.util.projectWizard.WizardInputField;
+import com.intellij.openapi.extensions.ExtensionPointName;
+import com.intellij.platform.ProjectTemplate;
+
+import javax.swing.*;
+
+public abstract class EduProjectTemplate implements ProjectTemplate {
+  public static final ExtensionPointName<EduProjectTemplate> EP_NAME = ExtensionPointName.create("com.jetbrains.edu.interactivelearning.intellij.EduProjectTemplate");
+
+  public static WizardInputField createWizardInputField(String id, final String label, final JComponent component) {
+    return new WizardInputField(id, id) {
+      @Override
+      public String getLabel() {
+        return label;
+      }
+
+      @Override
+      public JComponent getComponent() {
+        return component;
+      }
+
+      @Override
+      public String getValue() {
+        return null;
+      }
+    };
+  }
+}
diff --git a/python/educational/interactive-learning-intellij/src/EduProjectTemplateFactory.java b/python/educational/interactive-learning-intellij/src/EduProjectTemplateFactory.java
new file mode 100644 (file)
index 0000000..83df2c5
--- /dev/null
@@ -0,0 +1,20 @@
+import com.intellij.ide.util.projectWizard.WizardContext;
+import com.intellij.platform.ProjectTemplate;
+import com.intellij.platform.ProjectTemplatesFactory;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+public class EduProjectTemplateFactory extends ProjectTemplatesFactory {
+
+  @NotNull
+  @Override
+  public String[] getGroups() {
+    return new String[] {"Edu"};
+  }
+
+  @NotNull
+  @Override
+  public ProjectTemplate[] createTemplates(@Nullable String group, WizardContext context) {
+    return EduProjectTemplate.EP_NAME.getExtensions();
+  }
+}
\ No newline at end of file
index f5198390635249945685d5b4736d601700dbfea2..d7dfab93be752150ca4d786255108e699989283b 100644 (file)
@@ -33,7 +33,7 @@ public class StudyTreeStructureProvider implements TreeStructureProvider, DumbAw
       if (project != null) {
         if (node.getValue() instanceof PsiDirectory) {
           final PsiDirectory nodeValue = (PsiDirectory)node.getValue();
-          if (!nodeValue.getName().contains(EduNames.USER_TESTS)) {
+          if (!nodeValue.getName().contains(EduNames.USER_TESTS) && !nodeValue.getName().equals(".idea")) {
             StudyDirectoryNode newNode = new StudyDirectoryNode(project, nodeValue, settings);
             nodes.add(newNode);
           }
index d2a504027ab355594c94d2271965f238c1110d4f..3c5369f403de7ea79fb7c6a3f132e23e65ce7a67 100644 (file)
@@ -8,7 +8,7 @@
     <properties/>
     <border type="none"/>
     <children>
-      <grid id="54488" layout-manager="GridLayoutManager" row-count="2" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+      <grid id="54488" binding="myInfoPanel" layout-manager="GridLayoutManager" row-count="2" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
         <margin top="0" left="0" bottom="0" right="0"/>
         <constraints>
           <grid row="1" column="1" row-span="1" col-span="2" vsize-policy="2" hsize-policy="4" anchor="0" fill="3" indent="0" use-parent-layout="false">
index f425f597a322570bc3f64c4ad80d3df57d5330c3..679931cd2f2a946d4660c4737e8e9ac1ba873ee0 100644 (file)
@@ -26,6 +26,7 @@ public class StudyNewProjectPanel{
   private JLabel myAuthorLabel;
   private JLabel myDescriptionLabel;
   private JLabel myLabel;
+  private JPanel myInfoPanel;
   private final StudyProjectGenerator myGenerator;
   private static final String CONNECTION_ERROR = "<html>Failed to download courses.<br>Check your Internet connection.</html>";
   private static final String INVALID_COURSE = "Selected course is invalid";
@@ -133,4 +134,11 @@ public class StudyNewProjectPanel{
     }
   }
 
+  public JComboBox getCoursesComboBox() {
+    return myCoursesComboBox;
+  }
+
+  public JPanel getInfoPanel() {
+    return myInfoPanel;
+  }
 }