merge local course creation for IDEA to student plugin

This commit is contained in:
Liana.Bakradze
2017-03-07 12:16:39 +03:00
parent ffd1ac8bb3
commit 3100617f04
8 changed files with 293 additions and 1 deletions
@@ -2,5 +2,8 @@
<extensions defaultExtensionNs="com.intellij">
<projectTemplatesFactory implementation="com.jetbrains.edu.learning.intellij.EduIntelliJTemplateFactory"/>
</extensions>
<extensions defaultExtensionNs="Edu">
<eduIntelliJProjectTemplate implementation="com.jetbrains.edu.learning.intellij.localCourses.EduCustomCourseProjectTemplate"/>
</extensions>
</idea-plugin>
@@ -1,8 +1,12 @@
package com.jetbrains.edu.learning.intellij;
import com.intellij.lang.LanguageExtension;
import com.intellij.openapi.module.ModifiableModuleModel;
import com.intellij.openapi.project.Project;
import com.jetbrains.edu.learning.courseGeneration.StudyProjectGenerator;
import com.jetbrains.edu.learning.stepic.CourseInfo;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@SuppressWarnings("unused") //used in other educational plugins that are stored in separate repository
public interface EduCourseConfigurator {
@@ -10,4 +14,10 @@ public interface EduCourseConfigurator {
LanguageExtension<EduCourseConfigurator> INSTANCE = new LanguageExtension<>(EP_NAME);
default void configureModule(@NotNull final Project project) {}
default void createCourseFromCourseInfo(@NotNull ModifiableModuleModel moduleModel,
@NotNull Project project,
@NotNull StudyProjectGenerator generator,
@NotNull CourseInfo selectedCourse,
@Nullable String moduleDir) {}
}
@@ -0,0 +1,26 @@
package com.jetbrains.edu.learning.intellij.generation;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.jetbrains.edu.learning.StudyTaskManager;
import com.jetbrains.edu.learning.courseFormat.Course;
import com.jetbrains.edu.learning.courseGeneration.StudyProjectGenerator;
import org.jetbrains.annotations.NotNull;
import java.io.File;
public class EduProjectGenerator extends StudyProjectGenerator {
private static final Logger LOG = Logger.getInstance(EduProjectGenerator.class);
@Override
public void generateProject(@NotNull Project project, @NotNull VirtualFile baseDir) {
final Course course = getCourse(project);
if (course == null) {
LOG.warn("Failed to get course");
return;
}
StudyTaskManager.getInstance(project).setCourse(course);
course.setCourseDirectory(new File(OUR_COURSES_DIR, mySelectedCourseInfo.getName()).getAbsolutePath());
}
}
@@ -0,0 +1,102 @@
package com.jetbrains.edu.learning.intellij.localCourses;
import com.intellij.ide.util.projectWizard.*;
import com.intellij.lang.Language;
import com.intellij.openapi.module.ModifiableModuleModel;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleWithNameAlreadyExists;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ui.configuration.ModulesProvider;
import com.intellij.openapi.util.Conditions;
import com.intellij.openapi.util.InvalidDataException;
import com.jetbrains.edu.learning.courseGeneration.StudyProjectGenerator;
import com.jetbrains.edu.learning.intellij.EduCourseConfigurator;
import com.jetbrains.edu.learning.intellij.generation.EduProjectGenerator;
import com.jetbrains.edu.learning.stepic.CourseInfo;
import org.jdom.JDOMException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.io.IOException;
class EduCustomCourseModuleBuilder extends JavaModuleBuilder {
private EduProjectGenerator myGenerator = new EduProjectGenerator();
private CourseInfo mySelectedCourse;
@Nullable
@Override
public Module commitModule(@NotNull Project project, @Nullable ModifiableModuleModel model) {
String type = mySelectedCourse.getType();
String languageName = type.substring("pycharm ".length());
Language language = Language.findLanguageByID(languageName);
if (language != null) {
EduCourseConfigurator configurator = EduCourseConfigurator.INSTANCE.forLanguage(language);
if (configurator != null) {
configurator.configureModule(project);
}
}
return super.commitModule(project, model);
}
@Nullable
@Override
public String getBuilderId() {
return "custom.course.builder";
}
@Override
public ModuleWizardStep[] createWizardSteps(@NotNull WizardContext wizardContext, @NotNull ModulesProvider modulesProvider) {
return new ModuleWizardStep[]{new EduCourseSelectionSettingsStep(myGenerator)};
}
private class EduCourseSelectionSettingsStep extends ModuleWizardStep {
private final StudyProjectGenerator myGenerator;
EduCourseSelectionSettingsStep(StudyProjectGenerator generator) {
myGenerator = generator;
}
@Override
public JComponent getComponent() {
return new EduLocalCoursePanel(myGenerator, EduCustomCourseModuleBuilder.this).getContentPanel();
}
@Override
public void updateDataModel() {
}
}
@Nullable
@Override
public ModuleWizardStep modifySettingsStep(@NotNull SettingsStep settingsStep) {
return ProjectWizardStepFactory.getInstance().createJavaSettingsStep(settingsStep, this, Conditions.alwaysTrue());
}
void setSelectedCourse(CourseInfo selectedCourse) {
mySelectedCourse = selectedCourse;
}
@NotNull
@Override
public Module createModule(@NotNull ModifiableModuleModel moduleModel)
throws InvalidDataException, IOException, ModuleWithNameAlreadyExists, JDOMException, ConfigurationException {
Module baseModule = super.createModule(moduleModel);
if (mySelectedCourse != null) {
String type = mySelectedCourse.getType();
String languageName = type.substring("pycharm ".length());
Language language = Language.findLanguageByID(languageName);
if (language != null) {
EduCourseConfigurator configurator = EduCourseConfigurator.INSTANCE.forLanguage(language);
if (configurator != null) {
configurator.createCourseFromCourseInfo(moduleModel, baseModule.getProject(), myGenerator, mySelectedCourse, getModuleFileDirectory());
}
}
}
return baseModule;
}
}
@@ -0,0 +1,41 @@
package com.jetbrains.edu.learning.intellij.localCourses;
import com.intellij.icons.AllIcons;
import com.intellij.ide.util.projectWizard.AbstractModuleBuilder;
import com.intellij.openapi.ui.ValidationInfo;
import com.jetbrains.edu.learning.intellij.EduIntelliJProjectTemplate;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
class EduCustomCourseProjectTemplate implements EduIntelliJProjectTemplate {
@NotNull
@Override
public String getName() {
return "Load an existing course";
}
@Nullable
@Override
public String getDescription() {
return "Custom Course Addition";
}
@Override
public Icon getIcon() {
return AllIcons.General.SecondaryGroup;
}
@NotNull
@Override
public AbstractModuleBuilder createModuleBuilder() {
return new EduCustomCourseModuleBuilder();
}
@Nullable
@Override
public ValidationInfo validateSettings() {
return null;
}
}
@@ -0,0 +1,53 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.jetbrains.edu.learning.intellij.localCourses.EduLocalCoursePanel">
<grid id="27dc6" binding="myContentPanel" layout-manager="GridLayoutManager" row-count="3" 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>
<xy x="20" y="20" width="500" height="400"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<grid id="112b7" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<component id="ea213" class="javax.swing.JLabel">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Course Archive Path:"/>
</properties>
</component>
<component id="65e41" class="com.intellij.openapi.ui.TextFieldWithBrowseButton" binding="myCourseArchivePath">
<constraints>
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false">
<preferred-size width="150" height="-1"/>
</grid>
</constraints>
<properties/>
</component>
</children>
</grid>
<grid id="8a94f" binding="myInfoPanel" custom-create="true" layout-manager="GridLayoutManager" row-count="1" 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="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none"/>
<children/>
</grid>
<vspacer id="2b26e">
<constraints>
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
</constraints>
</vspacer>
</children>
</grid>
</form>
@@ -0,0 +1,56 @@
package com.jetbrains.edu.learning.intellij.localCourses;
import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory;
import com.intellij.openapi.ui.TextFieldWithBrowseButton;
import com.intellij.openapi.util.text.StringUtil;
import com.jetbrains.edu.learning.courseFormat.Course;
import com.jetbrains.edu.learning.courseGeneration.StudyProjectGenerator;
import com.jetbrains.edu.learning.stepic.CourseInfo;
import com.jetbrains.edu.learning.ui.StudyNewProjectPanel;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class EduLocalCoursePanel {
private final StudyProjectGenerator myGenerator;
private EduCustomCourseModuleBuilder myBuilder;
private JPanel myContentPanel;
private JPanel myInfoPanel;
private TextFieldWithBrowseButton myCourseArchivePath;
public EduLocalCoursePanel(final StudyProjectGenerator generator, EduCustomCourseModuleBuilder builder) {
myGenerator = generator;
myBuilder = builder;
myCourseArchivePath.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent actionEvent) {
String coursePath = myCourseArchivePath.getText();
CourseInfo courseInfo = generator.addLocalCourse(coursePath);
if (courseInfo != null) {
//TODO: REMOVE THIS after API CHANGE
myBuilder.setSelectedCourse(courseInfo);
myGenerator.setSelectedCourse(courseInfo);
//TODO: change API to do this!!!
// final String authorsString = Course.getAuthorsString(courseInfo.getAuthors());
// ((JLabel)myInfoPanel.getComponent(0)).setText(!StringUtil.isEmptyOrSpaces(authorsString) ? "Author: " + authorsString : "");
// ((JTextPane)myInfoPanel.getComponent(1)).setText(courseInfo.getDescription());
}
else {
//TODO: validate!!!
}
}
});
myCourseArchivePath.addBrowseFolderListener("Select Course Archive", null, null,
FileChooserDescriptorFactory.createSingleFileDescriptor());
}
public JPanel getContentPanel() {
return myContentPanel;
}
private void createUIComponents() {
StudyNewProjectPanel panel = new StudyNewProjectPanel(myGenerator);
myInfoPanel = panel.getInfoPanel();
}
}
+2 -1
View File
@@ -36,7 +36,8 @@
</library>
</orderEntry>
<orderEntry type="module" module-name="testFramework" scope="TEST" />
<orderEntry type="module" module-name="idea-ui" />
<orderEntry type="module" module-name="testExtensions" scope="TEST" />
<orderEntry type="module" module-name="idea-ui" />
<orderEntry type="module" module-name="openapi" />
</component>
</module>