mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
merge local course creation for IDEA to student plugin
This commit is contained in:
@@ -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>
|
||||
|
||||
|
||||
+10
@@ -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) {}
|
||||
}
|
||||
|
||||
+26
@@ -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());
|
||||
}
|
||||
}
|
||||
+102
@@ -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;
|
||||
}
|
||||
}
|
||||
+41
@@ -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;
|
||||
}
|
||||
}
|
||||
+53
@@ -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>
|
||||
+56
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
Reference in New Issue
Block a user