refactoring pycharm educational second iteration
extracted interactive-learning (language independent) and interactive-learning-python modules
@@ -1,27 +0,0 @@
|
||||
package icons;
|
||||
|
||||
import com.intellij.openapi.util.IconLoader;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
/**
|
||||
* NOTE THIS FILE IS AUTO-GENERATED
|
||||
* DO NOT EDIT IT BY HAND, run build/scripts/icons.gant instead
|
||||
*/
|
||||
public class StudyIcons {
|
||||
private static Icon load(String path) {
|
||||
return IconLoader.getIcon(path, StudyIcons.class);
|
||||
}
|
||||
|
||||
public static final Icon EducationalProjectType = load("/icons/com/jetbrains/python/edu/EducationalProjectType.png"); // 16x16
|
||||
public static final Icon Lesson = load("/icons/com/jetbrains/python/edu/Lesson.png"); // 16x16
|
||||
public static final Icon LessonCompl = load("/icons/com/jetbrains/python/edu/LessonCompl.png"); // 16x16
|
||||
public static final Icon Prev = load("/icons/com/jetbrains/python/edu/prev.png"); // 16x16
|
||||
public static final Icon Resolve = load("/icons/com/jetbrains/python/edu/resolve.png"); // 16x16
|
||||
public static final Icon Sandbox = load("/icons/com/jetbrains/python/edu/Sandbox.png"); // 16x16
|
||||
public static final Icon ShowHint = load("/icons/com/jetbrains/python/edu/showHint.png"); // 16x16
|
||||
public static final Icon Task = load("/icons/com/jetbrains/python/edu/Task.png"); // 16x16
|
||||
public static final Icon TaskCompl = load("/icons/com/jetbrains/python/edu/TaskCompl.png"); // 16x16
|
||||
public static final Icon TaskProbl = load("/icons/com/jetbrains/python/edu/TaskProbl.png"); // 16x16
|
||||
public static final Icon WatchInput = load("/icons/com/jetbrains/python/edu/WatchInput.png"); // 24x24
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
<?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$/tests" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/gen" isTestSource="false" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/resources" type="java-resource" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="module" module-name="platform-impl" />
|
||||
<orderEntry type="module" module-name="python-community" />
|
||||
<orderEntry type="module" module-name="lang-impl" />
|
||||
<orderEntry type="library" name="gson" level="project" />
|
||||
<orderEntry type="library" scope="TEST" name="JUnit4" level="project" />
|
||||
<orderEntry type="module" module-name="python-ide-community" />
|
||||
<orderEntry type="module" module-name="testFramework" scope="TEST" />
|
||||
</component>
|
||||
</module>
|
||||
@@ -1,82 +0,0 @@
|
||||
<!--suppress XmlUnboundNsPrefix -->
|
||||
<idea-plugin version="2">
|
||||
<id>com.jetbrains.python.edu.learn-python</id>
|
||||
<name>Educational plugin for PyCharm</name>
|
||||
<version>1.2</version>
|
||||
|
||||
<description><![CDATA[
|
||||
Educational plugin for students. This plugin allows to learn Python
|
||||
using intelligent PyCharm IDE.
|
||||
]]></description>
|
||||
|
||||
<change-notes><![CDATA[
|
||||
|
||||
]]>
|
||||
</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>
|
||||
|
||||
<project-components>
|
||||
<component>
|
||||
<implementation-class>com.jetbrains.python.edu.StudyTaskManager</implementation-class>
|
||||
<interface-class>com.jetbrains.python.edu.StudyTaskManager</interface-class>
|
||||
</component>
|
||||
</project-components>
|
||||
|
||||
<application-components>
|
||||
<component>
|
||||
<implementation-class>com.jetbrains.python.edu.StudyInitialConfigurator</implementation-class>
|
||||
<headless-implementation-class/>
|
||||
</component>
|
||||
</application-components>
|
||||
|
||||
<actions>
|
||||
<action id="CheckAction" class="com.jetbrains.python.edu.actions.StudyCheckAction" text="Check Task"
|
||||
description="Check current task">
|
||||
</action>
|
||||
<action id="PrevWindowAction" class="com.jetbrains.python.edu.actions.StudyPrevWindowAction" text="Previous Answer Placeholder"
|
||||
description="Navigate to the previous answer placeholder">
|
||||
</action>
|
||||
<action id="NextWindow" class="com.jetbrains.python.edu.actions.StudyNextWindowAction" text="Next Answer Placeholder"
|
||||
description="Navigate to the next answer holder">
|
||||
</action>
|
||||
<action id="PreviousTaskAction" class="com.jetbrains.python.edu.actions.StudyPreviousStudyTaskAction" text="Previous Task"
|
||||
description="Navigate to previous task"/>
|
||||
<action id="NextTaskAction" class="com.jetbrains.python.edu.actions.StudyNextStudyTaskAction" text="Next Task"
|
||||
description="Navigate to next task"/>
|
||||
<action id="RefreshTaskAction" class="com.jetbrains.python.edu.actions.StudyRefreshTaskFileAction" text="Reset Task File"
|
||||
description="Refresh current task"/>
|
||||
<action id="WatchInputAction" class="com.jetbrains.python.edu.actions.StudyEditInputAction" text="Watch Test Input"
|
||||
description="Watch test input "/>
|
||||
<action id="ShowHintAction" class="com.jetbrains.python.edu.actions.StudyShowHintAction" text="Show Hint for Answer Placeholder"
|
||||
description="Show hint for answer placeholder"/>
|
||||
<action id="StudyRunAction" class="com.jetbrains.python.edu.actions.StudyRunAction" text="Run File With Tests"
|
||||
description="Run your code with tests"/>
|
||||
<action id="WelcomeScreen.PythonIntro" class="com.jetbrains.python.edu.actions.StudyIntroductionCourseAction" icon="StudyIcons.EducationalProjectType">
|
||||
<add-to-group group-id="WelcomeScreen.QuickStart" anchor="first"/>
|
||||
</action>
|
||||
<action id="StudyWatchTutorial" class="com.jetbrains.python.edu.actions.StudyWatchTutorialAction">
|
||||
<add-to-group group-id="HelpMenu" anchor="first"/>
|
||||
</action>
|
||||
|
||||
</actions>
|
||||
|
||||
<extensions defaultExtensionNs="com.intellij">
|
||||
<toolWindow id="Course Description" anchor="right" factoryClass="com.jetbrains.python.edu.ui.StudyToolWindowFactory" conditionClass="com.jetbrains.python.edu.ui.StudyCondition"/>
|
||||
<fileEditorProvider implementation="com.jetbrains.python.edu.editor.StudyFileEditorProvider"/>
|
||||
<directoryProjectGenerator implementation="com.jetbrains.python.edu.StudyDirectoryProjectGenerator"/>
|
||||
<treeStructureProvider implementation="com.jetbrains.python.edu.projectView.StudyTreeStructureProvider"/>
|
||||
<applicationService serviceInterface="com.intellij.openapi.fileEditor.impl.EditorEmptyTextPainter"
|
||||
serviceImplementation="com.jetbrains.python.edu.StudyInstructionPainter" overrides="true"/>
|
||||
<errorHandler implementation="com.intellij.diagnostic.ITNReporter"/>
|
||||
</extensions>
|
||||
<extensions defaultExtensionNs="Pythonid">
|
||||
<visitorFilter language="Python" implementationClass="com.jetbrains.python.edu.highlighting.StudyVisitorFilter"/>
|
||||
</extensions>
|
||||
</idea-plugin>
|
||||
@@ -1,5 +0,0 @@
|
||||
package com.jetbrains.python.edu;
|
||||
|
||||
public interface StudyResourceManger {
|
||||
String USER_TESTER = "user_tester.py";
|
||||
}
|
||||
@@ -1,96 +0,0 @@
|
||||
package com.jetbrains.python.edu.actions;
|
||||
|
||||
import com.intellij.execution.ExecutionException;
|
||||
import com.intellij.execution.RunContentExecutor;
|
||||
import com.intellij.execution.configurations.GeneralCommandLine;
|
||||
import com.intellij.execution.process.OSProcessHandler;
|
||||
import com.intellij.execution.process.ProcessHandler;
|
||||
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.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.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 com.jetbrains.python.run.PythonTracebackFilter;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class StudyRunAction extends DumbAwareAction {
|
||||
private static final Logger LOG = Logger.getInstance(StudyRunAction.class.getName());
|
||||
public static final String ACTION_ID = "StudyRunAction";
|
||||
private ProcessHandler myHandler;
|
||||
|
||||
public void run(@NotNull final Project project, @NotNull final Sdk sdk) {
|
||||
if (myHandler != null && !myHandler.isProcessTerminated()) return;
|
||||
Editor selectedEditor = StudyEditor.getSelectedEditor(project);
|
||||
FileDocumentManager fileDocumentManager = FileDocumentManager.getInstance();
|
||||
assert selectedEditor != null;
|
||||
VirtualFile openedFile = fileDocumentManager.getFile(selectedEditor.getDocument());
|
||||
StudyTaskManager taskManager = StudyTaskManager.getInstance(project);
|
||||
if (openedFile != null && openedFile.getCanonicalPath() != null) {
|
||||
String filePath = openedFile.getCanonicalPath();
|
||||
GeneralCommandLine cmd = new GeneralCommandLine();
|
||||
cmd.withWorkDirectory(openedFile.getParent().getCanonicalPath());
|
||||
String pythonPath = sdk.getHomePath();
|
||||
if (pythonPath != null) {
|
||||
cmd.setExePath(pythonPath);
|
||||
TaskFile selectedTaskFile = taskManager.getTaskFile(openedFile);
|
||||
assert selectedTaskFile != null;
|
||||
Task currentTask = selectedTaskFile.getTask();
|
||||
if (!currentTask.getUserTests().isEmpty()) {
|
||||
cmd.addParameter(new File(project.getBaseDir().getPath(), StudyResourceManger.USER_TESTER).getPath());
|
||||
cmd.addParameter(pythonPath);
|
||||
cmd.addParameter(filePath);
|
||||
Process process;
|
||||
try {
|
||||
process = cmd.createProcess();
|
||||
}
|
||||
catch (ExecutionException e) {
|
||||
LOG.error(e);
|
||||
return;
|
||||
}
|
||||
myHandler = new OSProcessHandler(process);
|
||||
RunContentExecutor executor = new RunContentExecutor(project, myHandler).withFilter(new PythonTracebackFilter(project));
|
||||
Disposer.register(project, executor);
|
||||
executor.run();
|
||||
return;
|
||||
}
|
||||
try {
|
||||
cmd.addParameter(filePath);
|
||||
Process p = cmd.createProcess();
|
||||
myHandler = new OSProcessHandler(p);
|
||||
|
||||
RunContentExecutor executor = new RunContentExecutor(project, myHandler).withFilter(new PythonTracebackFilter(project));
|
||||
Disposer.register(project, executor);
|
||||
executor.run();
|
||||
}
|
||||
|
||||
catch (ExecutionException e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -15,9 +15,10 @@
|
||||
<orderEntry type="module" module-name="platform-main" />
|
||||
<orderEntry type="module" module-name="ShortcutPromoter" />
|
||||
<orderEntry type="module" module-name="python-educational" />
|
||||
<orderEntry type="module" module-name="learn-python" />
|
||||
<orderEntry type="module" module-name="course-creator" />
|
||||
<orderEntry type="module" module-name="course-creator-python" />
|
||||
<orderEntry type="module" module-name="interactive-learning" />
|
||||
<orderEntry type="module" module-name="interactive-learning-python" />
|
||||
<orderEntry type="module" module-name="hg4idea" />
|
||||
</component>
|
||||
</module>
|
||||
@@ -4,8 +4,26 @@
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/resources" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/tests" isTestSource="true" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="module" module-name="interactive-learning" />
|
||||
<orderEntry type="module" module-name="lang-impl" />
|
||||
<orderEntry type="module" module-name="python-community" />
|
||||
<orderEntry type="module" module-name="platform-impl" />
|
||||
<orderEntry type="module" module-name="python-ide-community" />
|
||||
<orderEntry type="library" name="gson" level="project" />
|
||||
<orderEntry type="module-library" scope="TEST">
|
||||
<library>
|
||||
<CLASSES>
|
||||
<root url="jar://$APPLICATION_HOME_DIR$/lib/junit.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES />
|
||||
</library>
|
||||
</orderEntry>
|
||||
<orderEntry type="module" module-name="testFramework" scope="TEST" />
|
||||
</component>
|
||||
</module>
|
||||
@@ -0,0 +1,43 @@
|
||||
<!--suppress XmlUnboundNsPrefix -->
|
||||
<idea-plugin version="2">
|
||||
<id>com.jetbrains.python.edu.interactivelearning.python</id>
|
||||
<name>Educational plugin for PyCharm</name>
|
||||
<version>2.0</version>
|
||||
|
||||
<description><![CDATA[
|
||||
Educational plugin for students. This plugin allows to learn Python
|
||||
using intelligent PyCharm IDE.
|
||||
]]></description>
|
||||
|
||||
<change-notes><![CDATA[
|
||||
|
||||
]]>
|
||||
</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>
|
||||
|
||||
<extensions defaultExtensionNs="com.intellij">
|
||||
<directoryProjectGenerator implementation="com.jetbrains.edu.learning.PyStudyDirectoryProjectGenerator"/>
|
||||
</extensions>
|
||||
<extensions defaultExtensionNs="Pythonid">
|
||||
<visitorFilter language="Python" implementationClass="com.jetbrains.edu.learning.highlighting.PyStudyVisitorFilter"/>
|
||||
</extensions>
|
||||
<extensions defaultExtensionNs="Edu">
|
||||
<StudyUtils implementation="com.jetbrains.edu.learning.PyStudyUtils"/>
|
||||
</extensions>
|
||||
<actions>
|
||||
<action id="WelcomeScreen.PythonIntro" class="com.jetbrains.edu.learning.actions.PyStudyIntroductionCourseAction" icon="InteractiveLearningPythonIcons.EducationalProjectType">
|
||||
<add-to-group group-id="WelcomeScreen.QuickStart" anchor="first"/>
|
||||
</action>
|
||||
<action id="StudyWatchTutorial" class="com.jetbrains.edu.learning.actions.PyStudyWatchTutorialAction">
|
||||
<add-to-group group-id="HelpMenu" anchor="first"/>
|
||||
</action>
|
||||
</actions>
|
||||
</idea-plugin>
|
||||
|
Before Width: | Height: | Size: 674 B After Width: | Height: | Size: 674 B |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 674 B After Width: | Height: | Size: 674 B |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
@@ -0,0 +1,95 @@
|
||||
package com.jetbrains.edu.learning;
|
||||
|
||||
import com.intellij.facet.ui.FacetEditorValidator;
|
||||
import com.intellij.facet.ui.FacetValidatorsManager;
|
||||
import com.intellij.facet.ui.ValidationResult;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.progress.ProcessCanceledException;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.platform.DirectoryProjectGenerator;
|
||||
import com.jetbrains.edu.learning.course.CourseInfo;
|
||||
import com.jetbrains.edu.learning.ui.StudyNewProjectPanel;
|
||||
import com.jetbrains.python.newProject.PythonProjectGenerator;
|
||||
import icons.InteractiveLearningPythonIcons;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.io.File;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
public class PyStudyDirectoryProjectGenerator extends PythonProjectGenerator implements DirectoryProjectGenerator {
|
||||
private final StudyProjectGenerator myGenerator;
|
||||
public ValidationResult myValidationResult = new ValidationResult("selected course is not valid");
|
||||
|
||||
public PyStudyDirectoryProjectGenerator() {
|
||||
myGenerator = new StudyProjectGenerator();
|
||||
myGenerator.addSettingsStateListener(new StudyProjectGenerator.SettingsListener() {
|
||||
@Override
|
||||
public void stateChanged(ValidationResult result) {
|
||||
setValidationResult(result);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Nls
|
||||
@NotNull
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Educational";
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Object showGenerationSettings(VirtualFile baseDir) throws ProcessCanceledException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Icon getLogo() {
|
||||
return InteractiveLearningPythonIcons.EducationalProjectType;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void generateProject(@NotNull final Project project, @NotNull final VirtualFile baseDir,
|
||||
@Nullable Object settings, @NotNull Module module) {
|
||||
myGenerator.generateProject(project, baseDir);
|
||||
}
|
||||
@NotNull
|
||||
@Override
|
||||
public ValidationResult validate(@NotNull String s) {
|
||||
return myValidationResult;
|
||||
}
|
||||
|
||||
public void setValidationResult(ValidationResult validationResult) {
|
||||
myValidationResult = validationResult;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public JPanel extendBasePanel() throws ProcessCanceledException {
|
||||
StudyNewProjectPanel settingsPanel = new StudyNewProjectPanel(myGenerator);
|
||||
settingsPanel.registerValidators(new FacetValidatorsManager() {
|
||||
public void registerValidator(FacetEditorValidator validator, JComponent... componentsToWatch) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
public void validate() {
|
||||
fireStateChanged();
|
||||
}
|
||||
});
|
||||
return settingsPanel.getContentPanel();
|
||||
}
|
||||
|
||||
public Map<CourseInfo, File> getCourses() {
|
||||
return myGenerator.getCourses();
|
||||
}
|
||||
|
||||
public void setSelectedCourse(CourseInfo course) {
|
||||
myGenerator.setSelectedCourse(course);
|
||||
}
|
||||
}
|
||||
@@ -1,36 +1,26 @@
|
||||
package com.jetbrains.python.edu;
|
||||
package com.jetbrains.edu.learning;
|
||||
|
||||
import com.intellij.execution.ExecutionException;
|
||||
import com.intellij.execution.configurations.GeneralCommandLine;
|
||||
import com.intellij.execution.process.ProcessOutput;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.module.ModuleManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.projectRoots.Sdk;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.jetbrains.python.edu.course.Course;
|
||||
import com.jetbrains.python.edu.course.Task;
|
||||
import com.jetbrains.edu.learning.course.Course;
|
||||
import com.jetbrains.edu.learning.course.Task;
|
||||
import com.jetbrains.python.sdk.PythonSdkType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.*;
|
||||
import java.io.File;
|
||||
import java.util.Map;
|
||||
|
||||
public class StudyTestRunner {
|
||||
public static final String STUDY_PREFIX="#educational_plugin";
|
||||
public static final String TEST_OK = "test OK";
|
||||
private static final String TEST_FAILED = "FAILED + ";
|
||||
public class PyStudyTestRunner extends StudyTestRunner {
|
||||
private static final String PYTHONPATH = "PYTHONPATH";
|
||||
private static final Logger LOG = Logger.getInstance(StudyTestRunner.class);
|
||||
private final Task myTask;
|
||||
private final VirtualFile myTaskDir;
|
||||
|
||||
public StudyTestRunner(Task task, VirtualFile taskDir) {
|
||||
myTask = task;
|
||||
myTaskDir = taskDir;
|
||||
PyStudyTestRunner(@NotNull final Task task, @NotNull final VirtualFile taskfile) {
|
||||
super(task, taskfile);
|
||||
}
|
||||
|
||||
public Process createCheckProcess(Project project, String executablePath) throws ExecutionException {
|
||||
Sdk sdk = PythonSdkType.findPythonSdk(ModuleManager.getInstance(project).getModules()[0]);
|
||||
File testRunner = new File(myTaskDir.getPath(), myTask.getTestFile());
|
||||
@@ -61,20 +51,4 @@ public class StudyTestRunner {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@NotNull
|
||||
public String getTestsOutput(@NotNull final ProcessOutput processOutput) {
|
||||
for (String line : processOutput.getStdoutLines()) {
|
||||
if (line.contains(STUDY_PREFIX)) {
|
||||
if (line.contains(TEST_OK)) {
|
||||
continue;
|
||||
}
|
||||
int messageStart = line.indexOf(TEST_FAILED);
|
||||
return line.substring(messageStart + TEST_FAILED.length());
|
||||
}
|
||||
}
|
||||
|
||||
return TEST_OK;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.jetbrains.edu.learning;
|
||||
|
||||
import com.intellij.execution.RunContentExecutor;
|
||||
import com.intellij.execution.configurations.GeneralCommandLine;
|
||||
import com.intellij.execution.process.ProcessHandler;
|
||||
import com.intellij.openapi.module.ModuleManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.projectRoots.Sdk;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.jetbrains.edu.learning.course.Task;
|
||||
import com.jetbrains.python.run.PythonTracebackFilter;
|
||||
import com.jetbrains.python.sdk.PythonSdkType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class PyStudyUtils implements StudyUtilsExtensionPoint {
|
||||
|
||||
@Override
|
||||
public Sdk findSdk(@NotNull final Project project) {
|
||||
return PythonSdkType.findPythonSdk(ModuleManager.getInstance(project).getModules()[0]);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getLinkToTutorial() {
|
||||
return "<html>If you'd like to learn" +
|
||||
" more about PyCharm " +
|
||||
"Educational Edition, " +
|
||||
"click <a href=\"https://www.jetbrains.com/pycharm-educational/quickstart/\">here</a> to watch a tutorial</html>";
|
||||
}
|
||||
|
||||
@Override
|
||||
public StudyTestRunner getTestRunner(@NotNull final Task task, @NotNull final VirtualFile taskDir) {
|
||||
return new PyStudyTestRunner(task, taskDir);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RunContentExecutor getExecutor(@NotNull final Project project, @NotNull final ProcessHandler handler) {
|
||||
return new RunContentExecutor(project, handler).withFilter(new PythonTracebackFilter(project));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCommandLineParameters(@NotNull final GeneralCommandLine cmd,
|
||||
@NotNull final Project project,
|
||||
@NotNull final String filePath,
|
||||
@NotNull final String pythonPath,
|
||||
@NotNull final Task currentTask) {
|
||||
if (!currentTask.getUserTests().isEmpty()) {
|
||||
cmd.addParameter(new File(project.getBaseDir().getPath(), StudyNames.USER_TESTER).getPath());
|
||||
cmd.addParameter(pythonPath);
|
||||
cmd.addParameter(filePath);
|
||||
}
|
||||
else {
|
||||
cmd.addParameter(filePath);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -13,7 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.jetbrains.python.edu.actions;
|
||||
package com.jetbrains.edu.learning.actions;
|
||||
|
||||
import com.intellij.ide.impl.ProjectUtil;
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
@@ -21,23 +21,23 @@ import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.project.ProjectManager;
|
||||
import com.intellij.openapi.projectRoots.Sdk;
|
||||
import com.jetbrains.edu.learning.PyStudyDirectoryProjectGenerator;
|
||||
import com.jetbrains.edu.learning.StudyUtils;
|
||||
import com.jetbrains.edu.learning.course.CourseInfo;
|
||||
import com.jetbrains.python.configuration.PyConfigurableInterpreterList;
|
||||
import com.jetbrains.python.edu.StudyDirectoryProjectGenerator;
|
||||
import com.jetbrains.python.edu.StudyUtils;
|
||||
import com.jetbrains.python.edu.course.CourseInfo;
|
||||
import com.jetbrains.python.newProject.actions.GenerateProjectCallback;
|
||||
import com.jetbrains.python.newProject.actions.ProjectSpecificSettingsStep;
|
||||
import icons.StudyIcons;
|
||||
import icons.InteractiveLearningPythonIcons;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class StudyIntroductionCourseAction extends AnAction {
|
||||
public class PyStudyIntroductionCourseAction extends AnAction {
|
||||
|
||||
public StudyIntroductionCourseAction() {
|
||||
super("Introduction to Python", "Introduction to Python", StudyIcons.EducationalProjectType);
|
||||
public PyStudyIntroductionCourseAction() {
|
||||
super("Introduction to Python", "Introduction to Python", InteractiveLearningPythonIcons.EducationalProjectType);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -48,7 +48,7 @@ public class StudyIntroductionCourseAction extends AnAction {
|
||||
}
|
||||
else {
|
||||
final GenerateProjectCallback callback = new GenerateProjectCallback();
|
||||
final StudyDirectoryProjectGenerator generator = new StudyDirectoryProjectGenerator();
|
||||
final PyStudyDirectoryProjectGenerator generator = new PyStudyDirectoryProjectGenerator();
|
||||
final Map<CourseInfo, File> courses = generator.getCourses();
|
||||
CourseInfo introCourse = null;
|
||||
for (CourseInfo info : courses.keySet()) {
|
||||
@@ -1,12 +1,12 @@
|
||||
package com.jetbrains.python.edu.actions;
|
||||
package com.jetbrains.edu.learning.actions;
|
||||
|
||||
import com.intellij.ide.BrowserUtil;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.project.DumbAwareAction;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class StudyWatchTutorialAction extends DumbAwareAction {
|
||||
public StudyWatchTutorialAction() {
|
||||
public class PyStudyWatchTutorialAction extends DumbAwareAction {
|
||||
public PyStudyWatchTutorialAction() {
|
||||
super("Learn more about PyCharm Educational Edition", null, null);
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package com.jetbrains.python.edu.highlighting;
|
||||
package com.jetbrains.edu.learning.highlighting;
|
||||
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.jetbrains.python.edu.StudyTaskManager;
|
||||
import com.jetbrains.edu.learning.StudyTaskManager;
|
||||
import com.jetbrains.python.inspections.PythonVisitorFilter;
|
||||
import com.jetbrains.python.inspections.unresolvedReference.PyUnresolvedReferencesInspection;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class StudyVisitorFilter implements PythonVisitorFilter {
|
||||
public class PyStudyVisitorFilter implements PythonVisitorFilter {
|
||||
@Override
|
||||
public boolean isSupported(@NotNull final Class visitorClass, @NotNull final PsiFile file) {
|
||||
if (StudyTaskManager.getInstance(file.getProject()).getCourse() == null) return true;
|
||||
@@ -0,0 +1,17 @@
|
||||
package icons;
|
||||
|
||||
import com.intellij.openapi.util.IconLoader;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
/**
|
||||
* NOTE THIS FILE IS AUTO-GENERATED
|
||||
* DO NOT EDIT IT BY HAND, run build/scripts/icons.gant instead
|
||||
*/
|
||||
public class InteractiveLearningPythonIcons {
|
||||
private static Icon load(String path) {
|
||||
return IconLoader.getIcon(path, InteractiveLearningPythonIcons.class);
|
||||
}
|
||||
|
||||
public static final Icon EducationalProjectType = load("/icons/com/jetbrains/edu/learning/EducationalProjectType.png"); // 16x16
|
||||
}
|
||||
@@ -1,32 +1,30 @@
|
||||
import com.google.gson.FieldNamingPolicy;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import com.jetbrains.python.edu.StudyUtils;
|
||||
import com.jetbrains.python.edu.course.Course;
|
||||
import com.jetbrains.edu.learning.StudyUtils;
|
||||
import com.jetbrains.edu.learning.course.Course;
|
||||
import com.jetbrains.python.PythonHelpersLocator;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.Reader;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* author: liana
|
||||
* data: 7/4/14.
|
||||
*/
|
||||
public class JsonParserTest {
|
||||
public class JsonParserTest extends TestCase {
|
||||
private Course myCourse = null;
|
||||
@Before
|
||||
public void setUp() throws FileNotFoundException {
|
||||
Reader reader = new InputStreamReader(new FileInputStream("testData/course.json"));
|
||||
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
Reader reader = new InputStreamReader(new FileInputStream(getTestDataPath() + "/course.json"));
|
||||
Gson gson = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES).create();
|
||||
myCourse = gson.fromJson(reader, Course.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCourseLevel() {
|
||||
assertEquals(myCourse.getName(), "Python для начинающих");
|
||||
assertEquals(StudyUtils.getFirst(myCourse.getLessons().get(1).getTaskList().get(0).getUserTests()).getInput(), "sum-input.txt");
|
||||
@@ -34,4 +32,7 @@ public class JsonParserTest {
|
||||
assertEquals(myCourse.getLessons().get(0).getTaskList().size(), 2);
|
||||
assertEquals(myCourse.getLessons().get(1).getTaskList().size(), 1);
|
||||
}
|
||||
protected String getTestDataPath() {
|
||||
return PythonHelpersLocator.getPythonCommunityPath() + "/edu/learn-python/testData";
|
||||
}
|
||||
}
|
||||
@@ -3,9 +3,9 @@ import com.intellij.openapi.command.CommandProcessor;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.fileEditor.FileDocumentManager;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.jetbrains.python.edu.StudyDocumentListener;
|
||||
import com.jetbrains.python.edu.course.TaskFile;
|
||||
import com.jetbrains.python.edu.course.TaskWindow;
|
||||
import com.jetbrains.edu.learning.StudyDocumentListener;
|
||||
import com.jetbrains.edu.learning.course.TaskFile;
|
||||
import com.jetbrains.edu.learning.course.TaskWindow;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -16,6 +16,9 @@ import org.jetbrains.annotations.NotNull;
|
||||
|
||||
|
||||
public class CCProjectGeneratorUtil {
|
||||
private CCProjectGeneratorUtil() {
|
||||
}
|
||||
|
||||
public static void generateProject(@NotNull final Project project, @NotNull final VirtualFile baseDir,
|
||||
@NotNull final String name, @NotNull final String author,
|
||||
@NotNull final String description) {
|
||||
|
||||
@@ -4,8 +4,11 @@
|
||||
<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="lang-impl" />
|
||||
<orderEntry type="library" name="gson" level="project" />
|
||||
</component>
|
||||
</module>
|
||||
@@ -0,0 +1,74 @@
|
||||
<!--suppress XmlUnboundNsPrefix -->
|
||||
<idea-plugin version="2">
|
||||
<id>com.jetbrains.edu.interactivelearning</id>
|
||||
<name>Educational plugin core</name>
|
||||
<version>2.0</version>
|
||||
|
||||
<description><![CDATA[
|
||||
Educational plugin core for students.
|
||||
]]></description>
|
||||
|
||||
<change-notes><![CDATA[
|
||||
|
||||
]]>
|
||||
</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>
|
||||
|
||||
<project-components>
|
||||
<component>
|
||||
<implementation-class>com.jetbrains.edu.learning.StudyTaskManager</implementation-class>
|
||||
<interface-class>com.jetbrains.edu.learning.StudyTaskManager</interface-class>
|
||||
</component>
|
||||
</project-components>
|
||||
|
||||
<application-components>
|
||||
<component>
|
||||
<implementation-class>com.jetbrains.edu.learning.StudyInitialConfigurator</implementation-class>
|
||||
<headless-implementation-class/>
|
||||
</component>
|
||||
</application-components>
|
||||
|
||||
<extensionPoints>
|
||||
<extensionPoint qualifiedName="Edu.StudyUtils" interface="com.jetbrains.edu.learning.StudyUtilsExtensionPoint"/>
|
||||
</extensionPoints>
|
||||
|
||||
<actions>
|
||||
<action id="CheckAction" class="com.jetbrains.edu.learning.actions.StudyCheckAction" text="Check Task"
|
||||
description="Check current task">
|
||||
</action>
|
||||
<action id="PrevWindowAction" class="com.jetbrains.edu.learning.actions.StudyPrevWindowAction" text="Previous Answer Placeholder"
|
||||
description="Navigate to the previous answer placeholder">
|
||||
</action>
|
||||
<action id="NextWindow" class="com.jetbrains.edu.learning.actions.StudyNextWindowAction" text="Next Answer Placeholder"
|
||||
description="Navigate to the next answer holder">
|
||||
</action>
|
||||
<action id="PreviousTaskAction" class="com.jetbrains.edu.learning.actions.StudyPreviousStudyTaskAction" text="Previous Task"
|
||||
description="Navigate to previous task"/>
|
||||
<action id="NextTaskAction" class="com.jetbrains.edu.learning.actions.StudyNextStudyTaskAction" text="Next Task"
|
||||
description="Navigate to next task"/>
|
||||
<action id="RefreshTaskAction" class="com.jetbrains.edu.learning.actions.StudyRefreshTaskFileAction" text="Reset Task File"
|
||||
description="Refresh current task"/>
|
||||
<action id="WatchInputAction" class="com.jetbrains.edu.learning.actions.StudyEditInputAction" text="Watch Test Input"
|
||||
description="Watch test input "/>
|
||||
<action id="ShowHintAction" class="com.jetbrains.edu.learning.actions.StudyShowHintAction" text="Show Hint for Answer Placeholder"
|
||||
description="Show hint for answer placeholder"/>
|
||||
<action id="StudyRunAction" class="com.jetbrains.edu.learning.actions.StudyRunAction" text="Run File With Tests"
|
||||
description="Run your code with tests"/>
|
||||
|
||||
</actions>
|
||||
|
||||
<extensions defaultExtensionNs="com.intellij">
|
||||
<toolWindow id="Course Description" anchor="right" factoryClass="com.jetbrains.edu.learning.ui.StudyToolWindowFactory" conditionClass="com.jetbrains.edu.learning.ui.StudyCondition"/>
|
||||
<fileEditorProvider implementation="com.jetbrains.edu.learning.editor.StudyFileEditorProvider"/>
|
||||
<treeStructureProvider implementation="com.jetbrains.edu.learning.projectView.StudyTreeStructureProvider"/>
|
||||
<applicationService serviceInterface="com.intellij.openapi.fileEditor.impl.EditorEmptyTextPainter"
|
||||
serviceImplementation="com.jetbrains.edu.learning.StudyInstructionPainter" overrides="true"/>
|
||||
<errorHandler implementation="com.intellij.diagnostic.ITNReporter"/>
|
||||
</extensions>
|
||||
</idea-plugin>
|
||||
|
Before Width: | Height: | Size: 285 B After Width: | Height: | Size: 285 B |
|
Before Width: | Height: | Size: 751 B After Width: | Height: | Size: 751 B |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 483 B After Width: | Height: | Size: 483 B |
|
Before Width: | Height: | Size: 265 B After Width: | Height: | Size: 265 B |
|
Before Width: | Height: | Size: 455 B After Width: | Height: | Size: 455 B |
|
Before Width: | Height: | Size: 160 B After Width: | Height: | Size: 160 B |
|
Before Width: | Height: | Size: 269 B After Width: | Height: | Size: 269 B |
|
Before Width: | Height: | Size: 269 B After Width: | Height: | Size: 269 B |
|
Before Width: | Height: | Size: 369 B After Width: | Height: | Size: 369 B |
|
Before Width: | Height: | Size: 822 B After Width: | Height: | Size: 822 B |
|
Before Width: | Height: | Size: 821 B After Width: | Height: | Size: 821 B |
|
Before Width: | Height: | Size: 368 B After Width: | Height: | Size: 368 B |
|
Before Width: | Height: | Size: 336 B After Width: | Height: | Size: 336 B |
|
Before Width: | Height: | Size: 738 B After Width: | Height: | Size: 738 B |
|
Before Width: | Height: | Size: 739 B After Width: | Height: | Size: 739 B |
|
Before Width: | Height: | Size: 337 B After Width: | Height: | Size: 337 B |
|
Before Width: | Height: | Size: 159 B After Width: | Height: | Size: 159 B |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 437 B After Width: | Height: | Size: 437 B |
|
Before Width: | Height: | Size: 393 B After Width: | Height: | Size: 393 B |
|
Before Width: | Height: | Size: 421 B After Width: | Height: | Size: 421 B |
|
Before Width: | Height: | Size: 410 B After Width: | Height: | Size: 410 B |
|
Before Width: | Height: | Size: 871 B After Width: | Height: | Size: 871 B |
@@ -1,12 +1,12 @@
|
||||
package com.jetbrains.python.edu;
|
||||
package com.jetbrains.edu.learning;
|
||||
|
||||
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.event.DocumentAdapter;
|
||||
import com.intellij.openapi.editor.event.DocumentEvent;
|
||||
import com.intellij.openapi.editor.impl.event.DocumentEventImpl;
|
||||
import com.jetbrains.python.edu.course.TaskFile;
|
||||
import com.jetbrains.python.edu.course.TaskWindow;
|
||||
import com.jetbrains.edu.learning.course.TaskFile;
|
||||
import com.jetbrains.edu.learning.course.TaskWindow;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.jetbrains.python.edu;
|
||||
package com.jetbrains.edu.learning;
|
||||
|
||||
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
@@ -12,9 +12,9 @@ import com.intellij.openapi.editor.event.EditorMouseEvent;
|
||||
import com.intellij.openapi.fileEditor.FileDocumentManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.jetbrains.python.edu.course.TaskFile;
|
||||
import com.jetbrains.python.edu.course.TaskWindow;
|
||||
import com.jetbrains.python.edu.editor.StudyEditor;
|
||||
import com.jetbrains.edu.learning.course.TaskFile;
|
||||
import com.jetbrains.edu.learning.course.TaskWindow;
|
||||
import com.jetbrains.edu.learning.editor.StudyEditor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.awt.*;
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.jetbrains.python.edu;
|
||||
package com.jetbrains.edu.learning;
|
||||
|
||||
import com.intellij.codeInsight.CodeInsightSettings;
|
||||
import com.intellij.ide.RecentProjectsManager;
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.jetbrains.python.edu;
|
||||
package com.jetbrains.edu.learning;
|
||||
|
||||
import com.intellij.openapi.actionSystem.ActionManager;
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
@@ -12,7 +12,7 @@ import com.intellij.ui.JBColor;
|
||||
import com.intellij.util.PairFunction;
|
||||
import com.intellij.util.ui.GraphicsUtil;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import com.jetbrains.python.edu.actions.*;
|
||||
import com.jetbrains.edu.learning.actions.*;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
@@ -32,7 +32,7 @@ public class StudyInstructionPainter extends EditorEmptyTextPainter {
|
||||
|
||||
UIUtil.TextPainter painter = new UIUtil.TextPainter().withLineSpacing(1.5f);
|
||||
|
||||
painter.appendLine("PyCharm Educational Edition").underlined(new JBColor(Gray._150, Gray._180));
|
||||
painter.appendLine("Educational Edition").underlined(new JBColor(Gray._150, Gray._180));
|
||||
addAction(painter, "Navigate to the next answer placeholder", StudyNextWindowAction.ACTION_ID, StudyNextWindowAction.SHORTCUT2, true);
|
||||
String shortcut1 = getShortcutText(StudyPrevWindowAction.ACTION_ID, StudyPrevWindowAction.SHORTCUT, false, false);
|
||||
String shortcut2 = getShortcutText(StudyNextWindowAction.ACTION_ID, StudyNextWindowAction.SHORTCUT, false, false);
|
||||
@@ -13,18 +13,17 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.jetbrains.python.edu;
|
||||
package com.jetbrains.edu.learning;
|
||||
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
|
||||
@NonNls
|
||||
public class StudyNames {
|
||||
public static final String INTRODUCTION_COURSE = "introduction_course";
|
||||
public static final String TASK_HTML = "task.html";
|
||||
public static final String TASK_TESTS = "tests.py";
|
||||
public static final String COURSES = "courses";
|
||||
public static final String LESSON = "lesson";
|
||||
public static final String TEST_HELPER = "test_helper.py";
|
||||
public static final String USER_TESTER = "user_tester.py";
|
||||
|
||||
private StudyNames() {
|
||||
}
|
||||
@@ -1,9 +1,7 @@
|
||||
package com.jetbrains.python.edu;
|
||||
package com.jetbrains.edu.learning;
|
||||
|
||||
import com.google.gson.*;
|
||||
import com.google.gson.stream.JsonReader;
|
||||
import com.intellij.facet.ui.FacetEditorValidator;
|
||||
import com.intellij.facet.ui.FacetValidatorsManager;
|
||||
import com.intellij.facet.ui.ValidationResult;
|
||||
import com.intellij.ide.projectView.ProjectView;
|
||||
import com.intellij.ide.projectView.impl.AbstractProjectViewPane;
|
||||
@@ -13,8 +11,6 @@ import com.intellij.openapi.application.ModalityState;
|
||||
import com.intellij.openapi.application.PathManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.fileEditor.FileEditorManager;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.progress.ProcessCanceledException;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Condition;
|
||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
@@ -24,29 +20,26 @@ import com.intellij.openapi.vfs.newvfs.NewVirtualFile;
|
||||
import com.intellij.openapi.vfs.newvfs.impl.VirtualDirectoryImpl;
|
||||
import com.intellij.openapi.wm.ex.ToolWindowManagerAdapter;
|
||||
import com.intellij.openapi.wm.ex.ToolWindowManagerEx;
|
||||
import com.intellij.platform.DirectoryProjectGenerator;
|
||||
import com.intellij.platform.templates.github.GeneratorException;
|
||||
import com.intellij.platform.templates.github.ZipUtil;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiManager;
|
||||
import com.jetbrains.python.edu.course.*;
|
||||
import com.jetbrains.python.edu.ui.StudyNewProjectPanel;
|
||||
import com.jetbrains.python.newProject.PythonProjectGenerator;
|
||||
import icons.StudyIcons;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.jetbrains.edu.learning.course.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.io.*;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
|
||||
public class StudyDirectoryProjectGenerator extends PythonProjectGenerator implements DirectoryProjectGenerator {
|
||||
private static final Logger LOG = Logger.getInstance(StudyDirectoryProjectGenerator.class.getName());
|
||||
public class StudyProjectGenerator {
|
||||
private static final Logger LOG = Logger.getInstance(StudyProjectGenerator.class.getName());
|
||||
private final List<SettingsListener> myListeners = ContainerUtil.newArrayList();
|
||||
private static final String REPO_URL = "https://github.com/JetBrains/pycharm-courses/archive/master.zip";
|
||||
private static final String USER_NAME = "PyCharm";
|
||||
private static final String COURSE_META_FILE = "course.json";
|
||||
@@ -59,15 +52,6 @@ public class StudyDirectoryProjectGenerator extends PythonProjectGenerator imple
|
||||
private Map<CourseInfo, File> myCourses = new HashMap<CourseInfo, File>();
|
||||
private File mySelectedCourseFile;
|
||||
private Project myProject;
|
||||
public ValidationResult myValidationResult = new ValidationResult("selected course is not valid");
|
||||
|
||||
@Nls
|
||||
@NotNull
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Educational";
|
||||
}
|
||||
|
||||
|
||||
public void setCourses(Map<CourseInfo, File> courses) {
|
||||
myCourses = courses;
|
||||
@@ -140,22 +124,7 @@ public class StudyDirectoryProjectGenerator extends PythonProjectGenerator imple
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Object showGenerationSettings(VirtualFile baseDir) throws ProcessCanceledException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Icon getLogo() {
|
||||
return StudyIcons.EducationalProjectType;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void generateProject(@NotNull final Project project, @NotNull final VirtualFile baseDir,
|
||||
@Nullable Object settings, @NotNull Module module) {
|
||||
public void generateProject(@NotNull final Project project, @NotNull final VirtualFile baseDir) {
|
||||
|
||||
myProject = project;
|
||||
Reader reader = null;
|
||||
@@ -336,42 +305,6 @@ public class StudyDirectoryProjectGenerator extends PythonProjectGenerator imple
|
||||
return courseInfo;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ValidationResult validate(@NotNull String s) {
|
||||
return myValidationResult;
|
||||
}
|
||||
|
||||
public void setValidationResult(ValidationResult validationResult) {
|
||||
myValidationResult = validationResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return courses from memory or from cash file or parses course directory
|
||||
*/
|
||||
public Map<CourseInfo, File> getCourses() {
|
||||
if (!myCourses.isEmpty()) {
|
||||
return myCourses;
|
||||
}
|
||||
if (myCoursesDir.exists()) {
|
||||
File cacheFile = new File(myCoursesDir, CACHE_NAME);
|
||||
if (cacheFile.exists()) {
|
||||
myCourses = getCoursesFromCache(cacheFile);
|
||||
if (!myCourses.isEmpty()) {
|
||||
return myCourses;
|
||||
}
|
||||
}
|
||||
myCourses = loadCourses();
|
||||
if (!myCourses.isEmpty()) {
|
||||
return myCourses;
|
||||
}
|
||||
}
|
||||
downloadAndUnzip(false);
|
||||
myCourses = loadCourses();
|
||||
flushCache();
|
||||
return myCourses;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes courses to cash file {@link com.jetbrains.python.edu.StudyDirectoryProjectGenerator#CACHE_NAME}
|
||||
*/
|
||||
@@ -417,7 +350,7 @@ public class StudyDirectoryProjectGenerator extends PythonProjectGenerator imple
|
||||
Map<CourseInfo, File> coursesFromCash = new HashMap<CourseInfo, File>();
|
||||
BufferedReader reader = null;
|
||||
try {
|
||||
reader = new BufferedReader(new InputStreamReader(new FileInputStream(cashFile)));
|
||||
reader = new BufferedReader(new InputStreamReader(new FileInputStream(cashFile)));
|
||||
String line;
|
||||
|
||||
while ((line = reader.readLine()) != null) {
|
||||
@@ -446,18 +379,43 @@ public class StudyDirectoryProjectGenerator extends PythonProjectGenerator imple
|
||||
return coursesFromCash;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public JPanel extendBasePanel() throws ProcessCanceledException {
|
||||
StudyNewProjectPanel settingsPanel = new StudyNewProjectPanel(this);
|
||||
settingsPanel.registerValidators(new FacetValidatorsManager() {
|
||||
public void registerValidator(FacetEditorValidator validator, JComponent... componentsToWatch) {
|
||||
throw new UnsupportedOperationException();
|
||||
/**
|
||||
* @return courses from memory or from cash file or parses course directory
|
||||
*/
|
||||
public Map<CourseInfo, File> getCourses() {
|
||||
if (!myCourses.isEmpty()) {
|
||||
return myCourses;
|
||||
}
|
||||
if (myCoursesDir.exists()) {
|
||||
File cacheFile = new File(myCoursesDir, CACHE_NAME);
|
||||
if (cacheFile.exists()) {
|
||||
myCourses = getCoursesFromCache(cacheFile);
|
||||
if (!myCourses.isEmpty()) {
|
||||
return myCourses;
|
||||
}
|
||||
}
|
||||
public void validate() {
|
||||
fireStateChanged();
|
||||
myCourses = loadCourses();
|
||||
if (!myCourses.isEmpty()) {
|
||||
return myCourses;
|
||||
}
|
||||
});
|
||||
return settingsPanel.getContentPanel();
|
||||
}
|
||||
downloadAndUnzip(false);
|
||||
myCourses = loadCourses();
|
||||
flushCache();
|
||||
return myCourses;
|
||||
}
|
||||
|
||||
public void addSettingsStateListener(@NotNull SettingsListener listener) {
|
||||
myListeners.add(listener);
|
||||
}
|
||||
|
||||
public interface SettingsListener {
|
||||
void stateChanged(ValidationResult result);
|
||||
}
|
||||
|
||||
public void fireStateChanged(ValidationResult result) {
|
||||
for (SettingsListener listener : myListeners) {
|
||||
listener.stateChanged(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,11 @@
|
||||
package com.jetbrains.python.edu;
|
||||
package com.jetbrains.edu.learning;
|
||||
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.fileEditor.FileDocumentManager;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.jetbrains.python.edu.course.Task;
|
||||
import com.jetbrains.python.edu.course.TaskFile;
|
||||
import com.jetbrains.python.edu.editor.StudyEditor;
|
||||
import com.jetbrains.edu.learning.course.Task;
|
||||
import com.jetbrains.edu.learning.course.TaskFile;
|
||||
import com.jetbrains.edu.learning.editor.StudyEditor;
|
||||
|
||||
public class StudyState {
|
||||
private final StudyEditor myStudyEditor;
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.jetbrains.python.edu;
|
||||
package com.jetbrains.edu.learning;
|
||||
|
||||
import com.intellij.ide.BrowserUtil;
|
||||
import com.intellij.ide.ui.UISettings;
|
||||
@@ -32,13 +32,13 @@ import com.intellij.openapi.vfs.VirtualFileManager;
|
||||
import com.intellij.openapi.wm.*;
|
||||
import com.intellij.util.ui.update.UiNotifyConnector;
|
||||
import com.intellij.util.xmlb.XmlSerializer;
|
||||
import com.jetbrains.python.edu.actions.*;
|
||||
import com.jetbrains.python.edu.course.Course;
|
||||
import com.jetbrains.python.edu.course.Lesson;
|
||||
import com.jetbrains.python.edu.course.Task;
|
||||
import com.jetbrains.python.edu.course.TaskFile;
|
||||
import com.jetbrains.python.edu.ui.StudyCondition;
|
||||
import com.jetbrains.python.edu.ui.StudyToolWindowFactory;
|
||||
import com.jetbrains.edu.learning.actions.*;
|
||||
import com.jetbrains.edu.learning.course.Course;
|
||||
import com.jetbrains.edu.learning.course.Lesson;
|
||||
import com.jetbrains.edu.learning.course.Task;
|
||||
import com.jetbrains.edu.learning.course.TaskFile;
|
||||
import com.jetbrains.edu.learning.ui.StudyCondition;
|
||||
import com.jetbrains.edu.learning.ui.StudyToolWindowFactory;
|
||||
import org.jdom.Element;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -201,10 +201,7 @@ public class StudyTaskManager implements ProjectComponent, PersistentStateCompon
|
||||
@Override
|
||||
public void run() {
|
||||
if (PropertiesComponent.getInstance().getBoolean("StudyShowPopup", true)) {
|
||||
String content = "<html>If you'd like to learn" +
|
||||
" more about PyCharm " +
|
||||
"Educational Edition, " +
|
||||
"click <a href=\"https://www.jetbrains.com/pycharm-educational/quickstart/\">here</a> to watch a tutorial</html>";
|
||||
String content = StudyUtils.getLinkToTutorial();
|
||||
final Notification notification =
|
||||
new Notification("Watch Tutorials!", "", content, NotificationType.INFORMATION, new UrlOpeningListener(true));
|
||||
Notifications.Bus.notify(notification);
|
||||
@@ -0,0 +1,38 @@
|
||||
package com.jetbrains.edu.learning;
|
||||
|
||||
import com.intellij.execution.ExecutionException;
|
||||
import com.intellij.execution.process.ProcessOutput;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.jetbrains.edu.learning.course.Task;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public abstract class StudyTestRunner {
|
||||
public static final String STUDY_PREFIX="#educational_plugin";
|
||||
public static final String TEST_OK = "test OK";
|
||||
private static final String TEST_FAILED = "FAILED + ";
|
||||
protected final Task myTask;
|
||||
protected final VirtualFile myTaskDir;
|
||||
|
||||
public StudyTestRunner(@NotNull final Task task, @NotNull final VirtualFile taskDir) {
|
||||
myTask = task;
|
||||
myTaskDir = taskDir;
|
||||
}
|
||||
|
||||
public abstract Process createCheckProcess(Project project, String executablePath) throws ExecutionException;
|
||||
|
||||
@NotNull
|
||||
public String getTestsOutput(@NotNull final ProcessOutput processOutput) {
|
||||
for (String line : processOutput.getStdoutLines()) {
|
||||
if (line.contains(STUDY_PREFIX)) {
|
||||
if (line.contains(TEST_OK)) {
|
||||
continue;
|
||||
}
|
||||
int messageStart = line.indexOf(TEST_FAILED);
|
||||
return line.substring(messageStart + TEST_FAILED.length());
|
||||
}
|
||||
}
|
||||
|
||||
return TEST_OK;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,8 @@
|
||||
package com.jetbrains.python.edu;
|
||||
package com.jetbrains.edu.learning;
|
||||
|
||||
import com.intellij.execution.RunContentExecutor;
|
||||
import com.intellij.execution.configurations.GeneralCommandLine;
|
||||
import com.intellij.execution.process.ProcessHandler;
|
||||
import com.intellij.ide.SaveAndSyncHandlerImpl;
|
||||
import com.intellij.ide.projectView.actions.MarkRootActionBase;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
@@ -11,7 +14,6 @@ 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;
|
||||
@@ -24,10 +26,9 @@ import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.vfs.VirtualFileManager;
|
||||
import com.intellij.openapi.wm.ToolWindowManager;
|
||||
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 com.jetbrains.edu.learning.course.*;
|
||||
import com.jetbrains.edu.learning.editor.StudyEditor;
|
||||
import com.jetbrains.edu.learning.ui.StudyToolWindowFactory;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -35,6 +36,9 @@ import java.io.*;
|
||||
import java.util.Collection;
|
||||
|
||||
public class StudyUtils {
|
||||
private StudyUtils() {
|
||||
}
|
||||
|
||||
private static final Logger LOG = Logger.getInstance(StudyUtils.class.getName());
|
||||
|
||||
public static void closeSilently(Closeable stream) {
|
||||
@@ -199,8 +203,13 @@ public class StudyUtils {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static Sdk findPythonSdk(@NotNull final Project project) {
|
||||
return PythonSdkType.findPythonSdk(ModuleManager.getInstance(project).getModules()[0]);
|
||||
public static Sdk findSdk(@NotNull final Project project) {
|
||||
final StudyUtilsExtensionPoint[] extensions =
|
||||
ApplicationManager.getApplication().getExtensions(StudyUtilsExtensionPoint.EP_NAME);
|
||||
if (extensions.length > 0) {
|
||||
return extensions[0].findSdk(project);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void markDirAsSourceRoot(@NotNull final VirtualFile dir, @NotNull final Project project) {
|
||||
@@ -224,4 +233,43 @@ public class StudyUtils {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static StudyTestRunner getTestRunner(@NotNull final Task task, @NotNull final VirtualFile taskDir) {
|
||||
final StudyUtilsExtensionPoint[] extensions =
|
||||
ApplicationManager.getApplication().getExtensions(StudyUtilsExtensionPoint.EP_NAME);
|
||||
if (extensions.length > 0) {
|
||||
return extensions[0].getTestRunner(task, taskDir);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static String getLinkToTutorial() {
|
||||
final StudyUtilsExtensionPoint[] extensions =
|
||||
ApplicationManager.getApplication().getExtensions(StudyUtilsExtensionPoint.EP_NAME);
|
||||
if (extensions.length > 0) {
|
||||
return extensions[0].getLinkToTutorial();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static RunContentExecutor getExecutor(@NotNull final Project project, @NotNull final ProcessHandler handler) {
|
||||
final StudyUtilsExtensionPoint[] extensions =
|
||||
ApplicationManager.getApplication().getExtensions(StudyUtilsExtensionPoint.EP_NAME);
|
||||
if (extensions.length > 0) {
|
||||
return extensions[0].getExecutor(project, handler);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void setCommandLineParameters(@NotNull final GeneralCommandLine cmd,
|
||||
@NotNull final Project project,
|
||||
@NotNull final String filePath,
|
||||
@NotNull final String pythonPath,
|
||||
@NotNull final Task currentTask) {
|
||||
final StudyUtilsExtensionPoint[] extensions =
|
||||
ApplicationManager.getApplication().getExtensions(StudyUtilsExtensionPoint.EP_NAME);
|
||||
if (extensions.length > 0) {
|
||||
extensions[0].setCommandLineParameters(cmd, project, filePath, pythonPath, currentTask);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.jetbrains.edu.learning;
|
||||
|
||||
import com.intellij.execution.RunContentExecutor;
|
||||
import com.intellij.execution.configurations.GeneralCommandLine;
|
||||
import com.intellij.execution.process.ProcessHandler;
|
||||
import com.intellij.openapi.extensions.ExtensionPointName;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.projectRoots.Sdk;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.jetbrains.edu.learning.course.Task;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public interface StudyUtilsExtensionPoint {
|
||||
ExtensionPointName<StudyUtilsExtensionPoint> EP_NAME = ExtensionPointName.create("Edu.StudyUtils");
|
||||
|
||||
@Nullable
|
||||
abstract Sdk findSdk(@NotNull final Project project);
|
||||
|
||||
abstract String getLinkToTutorial();
|
||||
|
||||
abstract StudyTestRunner getTestRunner(@NotNull final Task task, @NotNull final VirtualFile taskDir);
|
||||
|
||||
public RunContentExecutor getExecutor(@NotNull final Project project, @NotNull final ProcessHandler handler);
|
||||
|
||||
public void setCommandLineParameters(@NotNull final GeneralCommandLine cmd,
|
||||
@NotNull final Project project,
|
||||
@NotNull final String filePath,
|
||||
@NotNull final String pythonPath,
|
||||
@NotNull final Task currentTask);
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.jetbrains.python.edu;
|
||||
package com.jetbrains.edu.learning;
|
||||
|
||||
import com.intellij.codeInsight.hint.HintManager;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.jetbrains.python.edu.actions;
|
||||
package com.jetbrains.edu.learning.actions;
|
||||
|
||||
import com.intellij.execution.ExecutionException;
|
||||
import com.intellij.execution.process.CapturingProcessHandler;
|
||||
@@ -33,15 +33,15 @@ import com.intellij.openapi.wm.IdeFrame;
|
||||
import com.intellij.openapi.wm.WindowManager;
|
||||
import com.intellij.openapi.wm.ex.StatusBarEx;
|
||||
import com.intellij.openapi.wm.ex.WindowManagerEx;
|
||||
import com.jetbrains.python.edu.StudyDocumentListener;
|
||||
import com.jetbrains.python.edu.StudyState;
|
||||
import com.jetbrains.python.edu.StudyTestRunner;
|
||||
import com.jetbrains.python.edu.StudyUtils;
|
||||
import com.jetbrains.python.edu.course.StudyStatus;
|
||||
import com.jetbrains.python.edu.course.Task;
|
||||
import com.jetbrains.python.edu.course.TaskFile;
|
||||
import com.jetbrains.python.edu.course.TaskWindow;
|
||||
import com.jetbrains.python.edu.editor.StudyEditor;
|
||||
import com.jetbrains.edu.learning.StudyDocumentListener;
|
||||
import com.jetbrains.edu.learning.StudyState;
|
||||
import com.jetbrains.edu.learning.StudyTestRunner;
|
||||
import com.jetbrains.edu.learning.StudyUtils;
|
||||
import com.jetbrains.edu.learning.course.StudyStatus;
|
||||
import com.jetbrains.edu.learning.course.Task;
|
||||
import com.jetbrains.edu.learning.course.TaskFile;
|
||||
import com.jetbrains.edu.learning.course.TaskWindow;
|
||||
import com.jetbrains.edu.learning.editor.StudyEditor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
@@ -133,7 +133,7 @@ public class StudyCheckAction extends DumbAwareAction {
|
||||
final Task task = studyState.getTask();
|
||||
final VirtualFile taskDir = studyState.getTaskDir();
|
||||
flushWindows(task, taskDir);
|
||||
Sdk sdk = StudyUtils.findPythonSdk(project);
|
||||
final Sdk sdk = StudyUtils.findSdk(project);
|
||||
if (sdk == null) {
|
||||
createNoPythonInterpreterPopUp(project);
|
||||
return;
|
||||
@@ -149,7 +149,8 @@ public class StudyCheckAction extends DumbAwareAction {
|
||||
IdeFocusManager.getInstance(project).requestFocus(studyState.getEditor().getComponent(), true);
|
||||
}
|
||||
});
|
||||
final StudyTestRunner testRunner = new StudyTestRunner(task, taskDir);
|
||||
|
||||
final StudyTestRunner testRunner = StudyUtils.getTestRunner(task, taskDir);
|
||||
Process testProcess = null;
|
||||
try {
|
||||
final VirtualFile executablePath = getTaskVirtualFile(studyState, task, taskDir);
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.jetbrains.python.edu.actions;
|
||||
package com.jetbrains.edu.learning.actions;
|
||||
|
||||
import com.intellij.icons.AllIcons;
|
||||
import com.intellij.ide.ui.UISettings;
|
||||
@@ -20,13 +20,13 @@ import com.intellij.ui.tabs.TabInfo;
|
||||
import com.intellij.ui.tabs.TabsListener;
|
||||
import com.intellij.ui.tabs.impl.JBEditorTabs;
|
||||
import com.intellij.util.PlatformIcons;
|
||||
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.course.UserTest;
|
||||
import com.jetbrains.python.edu.editor.StudyEditor;
|
||||
import com.jetbrains.python.edu.ui.StudyTestContentPanel;
|
||||
import com.jetbrains.edu.learning.StudyTaskManager;
|
||||
import com.jetbrains.edu.learning.StudyUtils;
|
||||
import com.jetbrains.edu.learning.course.Task;
|
||||
import com.jetbrains.edu.learning.course.TaskFile;
|
||||
import com.jetbrains.edu.learning.course.UserTest;
|
||||
import com.jetbrains.edu.learning.editor.StudyEditor;
|
||||
import com.jetbrains.edu.learning.ui.StudyTestContentPanel;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
@@ -154,7 +154,7 @@ public class StudyEditInputAction extends DumbAwareAction {
|
||||
showInput(e.getProject());
|
||||
}
|
||||
|
||||
private class HintClosedListener extends JBPopupAdapter {
|
||||
private static class HintClosedListener extends JBPopupAdapter {
|
||||
private final Task myTask;
|
||||
private HintClosedListener(@NotNull final Task task) {
|
||||
myTask = task;
|
||||
@@ -1,7 +1,7 @@
|
||||
package com.jetbrains.python.edu.actions;
|
||||
package com.jetbrains.edu.learning.actions;
|
||||
|
||||
import com.jetbrains.python.edu.editor.StudyEditor;
|
||||
import com.jetbrains.python.edu.course.Task;
|
||||
import com.jetbrains.edu.learning.course.Task;
|
||||
import com.jetbrains.edu.learning.editor.StudyEditor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
@@ -1,8 +1,8 @@
|
||||
package com.jetbrains.python.edu.actions;
|
||||
package com.jetbrains.edu.learning.actions;
|
||||
|
||||
import com.intellij.icons.AllIcons;
|
||||
import com.jetbrains.python.edu.StudyUtils;
|
||||
import com.jetbrains.python.edu.course.TaskWindow;
|
||||
import com.jetbrains.edu.learning.StudyUtils;
|
||||
import com.jetbrains.edu.learning.course.TaskWindow;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
@@ -1,8 +1,8 @@
|
||||
package com.jetbrains.python.edu.actions;
|
||||
package com.jetbrains.edu.learning.actions;
|
||||
|
||||
import com.jetbrains.python.edu.StudyUtils;
|
||||
import com.jetbrains.python.edu.course.TaskWindow;
|
||||
import icons.StudyIcons;
|
||||
import com.jetbrains.edu.learning.StudyUtils;
|
||||
import com.jetbrains.edu.learning.course.TaskWindow;
|
||||
import icons.InteractiveLearningIcons;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -17,7 +17,7 @@ public class StudyPrevWindowAction extends StudyWindowNavigationAction {
|
||||
public static final String SHORTCUT = "ctrl shift pressed COMMA";
|
||||
|
||||
public StudyPrevWindowAction() {
|
||||
super("Navigate to the Previous Answer Placeholder", "Navigate to the previous answer placeholder", StudyIcons.Prev);
|
||||
super("Navigate to the Previous Answer Placeholder", "Navigate to the previous answer placeholder", InteractiveLearningIcons.Prev);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package com.jetbrains.python.edu.actions;
|
||||
package com.jetbrains.edu.learning.actions;
|
||||
|
||||
|
||||
import com.jetbrains.python.edu.editor.StudyEditor;
|
||||
import com.jetbrains.python.edu.course.Task;
|
||||
import com.jetbrains.edu.learning.course.Task;
|
||||
import com.jetbrains.edu.learning.editor.StudyEditor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.jetbrains.python.edu.actions;
|
||||
package com.jetbrains.edu.learning.actions;
|
||||
|
||||
import com.intellij.ide.projectView.ProjectView;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
@@ -18,11 +18,11 @@ import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.vfs.VfsUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.wm.IdeFocusManager;
|
||||
import com.jetbrains.python.edu.StudyDocumentListener;
|
||||
import com.jetbrains.python.edu.StudyTaskManager;
|
||||
import com.jetbrains.python.edu.StudyUtils;
|
||||
import com.jetbrains.python.edu.course.*;
|
||||
import com.jetbrains.python.edu.editor.StudyEditor;
|
||||
import com.jetbrains.edu.learning.StudyDocumentListener;
|
||||
import com.jetbrains.edu.learning.StudyTaskManager;
|
||||
import com.jetbrains.edu.learning.StudyUtils;
|
||||
import com.jetbrains.edu.learning.course.*;
|
||||
import com.jetbrains.edu.learning.editor.StudyEditor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.File;
|
||||
@@ -0,0 +1,82 @@
|
||||
package com.jetbrains.edu.learning.actions;
|
||||
|
||||
import com.intellij.execution.ExecutionException;
|
||||
import com.intellij.execution.RunContentExecutor;
|
||||
import com.intellij.execution.configurations.GeneralCommandLine;
|
||||
import com.intellij.execution.process.OSProcessHandler;
|
||||
import com.intellij.execution.process.ProcessHandler;
|
||||
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.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.edu.learning.StudyTaskManager;
|
||||
import com.jetbrains.edu.learning.StudyUtils;
|
||||
import com.jetbrains.edu.learning.course.Task;
|
||||
import com.jetbrains.edu.learning.course.TaskFile;
|
||||
import com.jetbrains.edu.learning.editor.StudyEditor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class StudyRunAction extends DumbAwareAction {
|
||||
private static final Logger LOG = Logger.getInstance(StudyRunAction.class.getName());
|
||||
public static final String ACTION_ID = "StudyRunAction";
|
||||
private ProcessHandler myHandler;
|
||||
|
||||
public void run(@NotNull final Project project, @NotNull final Sdk sdk) {
|
||||
if (myHandler != null && !myHandler.isProcessTerminated()) return;
|
||||
Editor selectedEditor = StudyEditor.getSelectedEditor(project);
|
||||
FileDocumentManager fileDocumentManager = FileDocumentManager.getInstance();
|
||||
assert selectedEditor != null;
|
||||
VirtualFile openedFile = fileDocumentManager.getFile(selectedEditor.getDocument());
|
||||
|
||||
if (openedFile != null && openedFile.getCanonicalPath() != null) {
|
||||
String filePath = openedFile.getCanonicalPath();
|
||||
executeFile(project, sdk, openedFile, filePath);
|
||||
}
|
||||
}
|
||||
|
||||
private void executeFile(@NotNull final Project project, @NotNull final Sdk sdk,
|
||||
@NotNull final VirtualFile openedFile, @NotNull final String filePath) {
|
||||
StudyTaskManager taskManager = StudyTaskManager.getInstance(project);
|
||||
GeneralCommandLine cmd = new GeneralCommandLine();
|
||||
cmd.withWorkDirectory(openedFile.getParent().getCanonicalPath());
|
||||
String sdkHomePath = sdk.getHomePath();
|
||||
if (sdkHomePath != null) {
|
||||
cmd.setExePath(sdkHomePath);
|
||||
TaskFile selectedTaskFile = taskManager.getTaskFile(openedFile);
|
||||
assert selectedTaskFile != null;
|
||||
Task currentTask = selectedTaskFile.getTask();
|
||||
Process process;
|
||||
StudyUtils.setCommandLineParameters(cmd, project, filePath, sdkHomePath, currentTask);
|
||||
|
||||
try {
|
||||
process = cmd.createProcess();
|
||||
}
|
||||
catch (ExecutionException e) {
|
||||
LOG.error(e);
|
||||
return;
|
||||
}
|
||||
myHandler = new OSProcessHandler(process);
|
||||
RunContentExecutor executor = StudyUtils.getExecutor(project, myHandler);
|
||||
Disposer.register(project, executor);
|
||||
executor.run();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public void actionPerformed(@NotNull AnActionEvent e) {
|
||||
Project project = e.getProject();
|
||||
if (project == null) {
|
||||
return;
|
||||
}
|
||||
Sdk sdk = StudyUtils.findSdk(project);
|
||||
if (sdk == null) {
|
||||
return;
|
||||
}
|
||||
run(project, sdk);
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.jetbrains.python.edu.actions;
|
||||
package com.jetbrains.edu.learning.actions;
|
||||
|
||||
import com.intellij.codeInsight.documentation.DocumentationComponent;
|
||||
import com.intellij.codeInsight.documentation.DocumentationManager;
|
||||
@@ -13,13 +13,13 @@ import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiManager;
|
||||
import com.jetbrains.python.edu.StudyState;
|
||||
import com.jetbrains.python.edu.StudyTaskManager;
|
||||
import com.jetbrains.python.edu.StudyUtils;
|
||||
import com.jetbrains.python.edu.course.Course;
|
||||
import com.jetbrains.python.edu.course.TaskWindow;
|
||||
import com.jetbrains.python.edu.editor.StudyEditor;
|
||||
import icons.StudyIcons;
|
||||
import com.jetbrains.edu.learning.StudyState;
|
||||
import com.jetbrains.edu.learning.StudyTaskManager;
|
||||
import com.jetbrains.edu.learning.StudyUtils;
|
||||
import com.jetbrains.edu.learning.course.Course;
|
||||
import com.jetbrains.edu.learning.course.TaskWindow;
|
||||
import com.jetbrains.edu.learning.editor.StudyEditor;
|
||||
import icons.InteractiveLearningIcons;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -32,7 +32,7 @@ public class StudyShowHintAction extends DumbAwareAction {
|
||||
public static final String HINT_NOT_AVAILABLE = "There is no hint for this answer placeholder";
|
||||
|
||||
public StudyShowHintAction() {
|
||||
super("Show hint", "Show hint", StudyIcons.ShowHint);
|
||||
super("Show hint", "Show hint", InteractiveLearningIcons.ShowHint);
|
||||
}
|
||||
|
||||
public void actionPerformed(@NotNull AnActionEvent e) {
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.jetbrains.python.edu.actions;
|
||||
package com.jetbrains.edu.learning.actions;
|
||||
|
||||
import com.intellij.ide.projectView.ProjectView;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
@@ -14,11 +14,11 @@ import com.intellij.openapi.wm.ToolWindow;
|
||||
import com.intellij.openapi.wm.ToolWindowId;
|
||||
import com.intellij.openapi.wm.ToolWindowManager;
|
||||
import com.intellij.util.ui.tree.TreeUtil;
|
||||
import com.jetbrains.python.edu.StudyState;
|
||||
import com.jetbrains.python.edu.course.Lesson;
|
||||
import com.jetbrains.python.edu.course.Task;
|
||||
import com.jetbrains.python.edu.course.TaskFile;
|
||||
import com.jetbrains.python.edu.editor.StudyEditor;
|
||||
import com.jetbrains.edu.learning.StudyState;
|
||||
import com.jetbrains.edu.learning.course.Lesson;
|
||||
import com.jetbrains.edu.learning.course.Task;
|
||||
import com.jetbrains.edu.learning.course.TaskFile;
|
||||
import com.jetbrains.edu.learning.editor.StudyEditor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.jetbrains.python.edu.actions;
|
||||
package com.jetbrains.edu.learning.actions;
|
||||
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
@@ -6,11 +6,11 @@ import com.intellij.openapi.fileEditor.FileDocumentManager;
|
||||
import com.intellij.openapi.project.DumbAwareAction;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.jetbrains.python.edu.StudyTaskManager;
|
||||
import com.jetbrains.python.edu.StudyUtils;
|
||||
import com.jetbrains.python.edu.course.TaskFile;
|
||||
import com.jetbrains.python.edu.course.TaskWindow;
|
||||
import com.jetbrains.python.edu.editor.StudyEditor;
|
||||
import com.jetbrains.edu.learning.StudyTaskManager;
|
||||
import com.jetbrains.edu.learning.StudyUtils;
|
||||
import com.jetbrains.edu.learning.course.TaskFile;
|
||||
import com.jetbrains.edu.learning.course.TaskWindow;
|
||||
import com.jetbrains.edu.learning.editor.StudyEditor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.jetbrains.python.edu.course;
|
||||
package com.jetbrains.edu.learning.course;
|
||||
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.jetbrains.python.edu.course;
|
||||
package com.jetbrains.edu.learning.course;
|
||||
|
||||
/**
|
||||
* Implementation of class which contains information to be shawn in course description in tool window
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.jetbrains.python.edu.course;
|
||||
package com.jetbrains.edu.learning.course;
|
||||
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
@@ -58,7 +58,7 @@ public class Lesson implements Stateful {
|
||||
*
|
||||
* @param courseDir project directory of course
|
||||
* @param resourceRoot directory where original lesson stored
|
||||
* @throws java.io.IOException
|
||||
* @throws IOException
|
||||
*/
|
||||
public void create(@NotNull final VirtualFile courseDir, @NotNull final File resourceRoot,
|
||||
@NotNull final Project project) throws IOException {
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.jetbrains.python.edu.course;
|
||||
package com.jetbrains.edu.learning.course;
|
||||
|
||||
/**
|
||||
* Implementation of class which contains information about student progress in current lesson
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.jetbrains.python.edu.course;
|
||||
package com.jetbrains.edu.learning.course;
|
||||
|
||||
public interface Stateful {
|
||||
StudyStatus getStatus();
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.jetbrains.python.edu.course;
|
||||
package com.jetbrains.edu.learning.course;
|
||||
|
||||
/**
|
||||
* @see {@link TaskWindow#myStatus}
|
||||
@@ -1,10 +1,10 @@
|
||||
package com.jetbrains.python.edu.course;
|
||||
package com.jetbrains.edu.learning.course;
|
||||
|
||||
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 com.jetbrains.edu.learning.StudyUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -83,7 +83,7 @@ public class Task implements Stateful {
|
||||
*
|
||||
* @param lessonDir project directory of lesson which task belongs to
|
||||
* @param resourceRoot directory where original task file stored
|
||||
* @throws java.io.IOException
|
||||
* @throws IOException
|
||||
*/
|
||||
public void create(@NotNull final VirtualFile lessonDir, @NotNull final File resourceRoot,
|
||||
@NotNull final Project project) throws IOException {
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.jetbrains.python.edu.course;
|
||||
package com.jetbrains.edu.learning.course;
|
||||
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
@@ -13,8 +13,8 @@ import com.intellij.openapi.editor.markup.RangeHighlighter;
|
||||
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 com.jetbrains.python.edu.TaskWindowDeleteHandler;
|
||||
import com.jetbrains.edu.learning.StudyUtils;
|
||||
import com.jetbrains.edu.learning.TaskWindowDeleteHandler;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -85,7 +85,7 @@ public class TaskFile implements Stateful {
|
||||
*
|
||||
* @param taskDir project directory of task which task file belongs to
|
||||
* @param resourceRoot directory where original task file stored
|
||||
* @throws java.io.IOException
|
||||
* @throws IOException
|
||||
*/
|
||||
public void create(@NotNull final VirtualFile taskDir, @NotNull final File resourceRoot,
|
||||
@NotNull final String name) throws IOException {
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.jetbrains.python.edu.course;
|
||||
package com.jetbrains.edu.learning.course;
|
||||
|
||||
import com.intellij.execution.ExecutionException;
|
||||
import com.intellij.execution.process.CapturingProcessHandler;
|
||||
@@ -18,9 +18,9 @@ import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.ui.JBColor;
|
||||
import com.jetbrains.python.edu.StudyDocumentListener;
|
||||
import com.jetbrains.python.edu.StudyTestRunner;
|
||||
import com.jetbrains.python.edu.StudyUtils;
|
||||
import com.jetbrains.edu.learning.StudyDocumentListener;
|
||||
import com.jetbrains.edu.learning.StudyTestRunner;
|
||||
import com.jetbrains.edu.learning.StudyUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.File;
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.jetbrains.python.edu.course;
|
||||
package com.jetbrains.edu.learning.course;
|
||||
|
||||
public class UserTest {
|
||||
private String input;
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.jetbrains.python.edu.editor;
|
||||
package com.jetbrains.edu.learning.editor;
|
||||
|
||||
import com.intellij.codeHighlighting.BackgroundEditorHighlighter;
|
||||
import com.intellij.icons.AllIcons;
|
||||
@@ -34,13 +34,13 @@ import com.intellij.ui.HideableTitledPanel;
|
||||
import com.intellij.ui.JBColor;
|
||||
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;
|
||||
import icons.StudyIcons;
|
||||
import com.jetbrains.edu.learning.StudyDocumentListener;
|
||||
import com.jetbrains.edu.learning.StudyTaskManager;
|
||||
import com.jetbrains.edu.learning.StudyUtils;
|
||||
import com.jetbrains.edu.learning.actions.*;
|
||||
import com.jetbrains.edu.learning.course.Task;
|
||||
import com.jetbrains.edu.learning.course.TaskFile;
|
||||
import icons.InteractiveLearningIcons;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -205,13 +205,13 @@ public class StudyEditor implements TextEditor {
|
||||
}
|
||||
|
||||
private void initializeButtons(@NotNull final JPanel taskActionsPanel, @NotNull final TaskFile taskFile) {
|
||||
myCheckButton = addButton(taskActionsPanel, StudyCheckAction.ACTION_ID, StudyIcons.Resolve, StudyCheckAction.SHORTCUT);
|
||||
myPrevTaskButton = addButton(taskActionsPanel, StudyPreviousStudyTaskAction.ACTION_ID, StudyIcons.Prev, StudyPreviousStudyTaskAction.SHORTCUT);
|
||||
myCheckButton = addButton(taskActionsPanel, StudyCheckAction.ACTION_ID, InteractiveLearningIcons.Resolve, StudyCheckAction.SHORTCUT);
|
||||
myPrevTaskButton = addButton(taskActionsPanel, StudyPreviousStudyTaskAction.ACTION_ID, InteractiveLearningIcons.Prev, StudyPreviousStudyTaskAction.SHORTCUT);
|
||||
myNextTaskButton = addButton(taskActionsPanel, StudyNextStudyTaskAction.ACTION_ID, AllIcons.Actions.Forward, StudyNextStudyTaskAction.SHORTCUT);
|
||||
myRefreshButton = addButton(taskActionsPanel, StudyRefreshTaskFileAction.ACTION_ID, AllIcons.Actions.Refresh, StudyRefreshTaskFileAction.SHORTCUT);
|
||||
JButton myShowHintButton = addButton(taskActionsPanel, StudyShowHintAction.ACTION_ID, StudyIcons.ShowHint, StudyShowHintAction.SHORTCUT);
|
||||
JButton myShowHintButton = addButton(taskActionsPanel, StudyShowHintAction.ACTION_ID, InteractiveLearningIcons.ShowHint, StudyShowHintAction.SHORTCUT);
|
||||
if (!taskFile.getTask().getUserTests().isEmpty()) {
|
||||
final Sdk sdk = StudyUtils.findPythonSdk(myProject);
|
||||
final Sdk sdk = StudyUtils.findSdk(myProject);
|
||||
if (sdk != null) {
|
||||
JButton runButton = addButton(taskActionsPanel, StudyRunAction.ACTION_ID, AllIcons.General.Run, null);
|
||||
runButton.addActionListener(new ActionListener() {
|
||||
@@ -221,7 +221,7 @@ public class StudyEditor implements TextEditor {
|
||||
studyRunAction.run(myProject, sdk);
|
||||
}
|
||||
});
|
||||
JButton watchInputButton = addButton(taskActionsPanel, "WatchInputAction", StudyIcons.WatchInput, null);
|
||||
JButton watchInputButton = addButton(taskActionsPanel, "WatchInputAction", InteractiveLearningIcons.WatchInput, null);
|
||||
watchInputButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.jetbrains.python.edu.editor;
|
||||
package com.jetbrains.edu.learning.editor;
|
||||
|
||||
import com.intellij.openapi.fileEditor.FileEditor;
|
||||
import com.intellij.openapi.fileEditor.FileEditorPolicy;
|
||||
@@ -8,10 +8,10 @@ import com.intellij.openapi.fileEditor.impl.text.TextEditorProvider;
|
||||
import com.intellij.openapi.project.DumbAware;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.jetbrains.edu.learning.StudyTaskManager;
|
||||
import com.jetbrains.edu.learning.course.TaskFile;
|
||||
import org.jdom.Element;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import com.jetbrains.python.edu.StudyTaskManager;
|
||||
import com.jetbrains.python.edu.course.TaskFile;
|
||||
|
||||
/**
|
||||
* User: lia
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.jetbrains.python.edu.projectView;
|
||||
package com.jetbrains.edu.learning.projectView;
|
||||
|
||||
import com.intellij.ide.projectView.PresentationData;
|
||||
import com.intellij.ide.projectView.ProjectView;
|
||||
@@ -11,10 +11,10 @@ import com.intellij.psi.PsiDirectory;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.ui.JBColor;
|
||||
import com.intellij.ui.SimpleTextAttributes;
|
||||
import com.jetbrains.python.edu.StudyTaskManager;
|
||||
import com.jetbrains.python.edu.StudyUtils;
|
||||
import com.jetbrains.python.edu.course.*;
|
||||
import icons.StudyIcons;
|
||||
import com.jetbrains.edu.learning.StudyTaskManager;
|
||||
import com.jetbrains.edu.learning.StudyUtils;
|
||||
import com.jetbrains.edu.learning.course.*;
|
||||
import icons.InteractiveLearningIcons;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
@@ -35,7 +35,7 @@ public class StudyDirectoryNode extends PsiDirectoryNode {
|
||||
|
||||
@Override
|
||||
protected void updateImpl(PresentationData data) {
|
||||
data.setIcon(StudyIcons.Task);
|
||||
data.setIcon(InteractiveLearningIcons.Task);
|
||||
String valueName = myValue.getName();
|
||||
StudyTaskManager studyTaskManager = StudyTaskManager.getInstance(myProject);
|
||||
Course course = studyTaskManager.getCourse();
|
||||
@@ -72,7 +72,7 @@ public class StudyDirectoryNode extends PsiDirectoryNode {
|
||||
if (myValue.getParent() != null) {
|
||||
if (!myValue.getParent().getName().contains(Course.SANDBOX_DIR)) {
|
||||
data.setPresentableText(Course.SANDBOX_DIR);
|
||||
data.setIcon(StudyIcons.Sandbox);
|
||||
data.setIcon(InteractiveLearningIcons.Sandbox);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -94,16 +94,16 @@ public class StudyDirectoryNode extends PsiDirectoryNode {
|
||||
StudyStatus taskStatus = stateful.getStatus();
|
||||
switch (taskStatus) {
|
||||
case Unchecked: {
|
||||
updatePresentation(data, additionalName, JBColor.BLACK, stateful instanceof Lesson ? StudyIcons.Lesson : StudyIcons.Task);
|
||||
updatePresentation(data, additionalName, JBColor.BLACK, stateful instanceof Lesson ? InteractiveLearningIcons.Lesson : InteractiveLearningIcons.Task);
|
||||
break;
|
||||
}
|
||||
case Solved: {
|
||||
updatePresentation(data, additionalName, new JBColor(new Color(0, 134, 0), new Color(98, 150, 85)),
|
||||
stateful instanceof Lesson ? StudyIcons.LessonCompl : StudyIcons.TaskCompl);
|
||||
stateful instanceof Lesson ? InteractiveLearningIcons.LessonCompl : InteractiveLearningIcons.TaskCompl);
|
||||
break;
|
||||
}
|
||||
case Failed: {
|
||||
updatePresentation(data, additionalName, JBColor.RED, stateful instanceof Lesson ? StudyIcons.Lesson : StudyIcons.TaskProbl);
|
||||
updatePresentation(data, additionalName, JBColor.RED, stateful instanceof Lesson ? InteractiveLearningIcons.Lesson : InteractiveLearningIcons.TaskProbl);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.jetbrains.python.edu.projectView;
|
||||
package com.jetbrains.edu.learning.projectView;
|
||||
|
||||
import com.intellij.ide.projectView.TreeStructureProvider;
|
||||
import com.intellij.ide.projectView.ViewSettings;
|
||||
@@ -8,10 +8,10 @@ import com.intellij.openapi.project.DumbAware;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiDirectory;
|
||||
import com.jetbrains.python.edu.StudyTaskManager;
|
||||
import com.jetbrains.python.edu.course.Course;
|
||||
import com.jetbrains.python.edu.course.Task;
|
||||
import com.jetbrains.python.edu.course.TaskFile;
|
||||
import com.jetbrains.edu.learning.StudyTaskManager;
|
||||
import com.jetbrains.edu.learning.course.Course;
|
||||
import com.jetbrains.edu.learning.course.Task;
|
||||
import com.jetbrains.edu.learning.course.TaskFile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package com.jetbrains.python.edu.ui;
|
||||
package com.jetbrains.edu.learning.ui;
|
||||
|
||||
import com.intellij.openapi.project.DumbAware;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Condition;
|
||||
import com.jetbrains.python.edu.StudyTaskManager;
|
||||
import com.jetbrains.edu.learning.StudyTaskManager;
|
||||
|
||||
/**
|
||||
* author: liana
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.jetbrains.python.edu.ui.StudyNewProjectPanel">
|
||||
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.jetbrains.edu.learning.ui.StudyNewProjectPanel">
|
||||
<grid id="27dc6" binding="myContentPanel" layout-manager="GridLayoutManager" row-count="2" column-count="4" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.jetbrains.python.edu.ui;
|
||||
package com.jetbrains.edu.learning.ui;
|
||||
|
||||
import com.intellij.facet.ui.FacetValidatorsManager;
|
||||
import com.intellij.facet.ui.ValidationResult;
|
||||
@@ -7,9 +7,9 @@ import com.intellij.openapi.fileChooser.FileChooser;
|
||||
import com.intellij.openapi.fileChooser.FileChooserDescriptor;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.jetbrains.python.edu.StudyDirectoryProjectGenerator;
|
||||
import com.jetbrains.python.edu.StudyUtils;
|
||||
import com.jetbrains.python.edu.course.CourseInfo;
|
||||
import com.jetbrains.edu.learning.StudyProjectGenerator;
|
||||
import com.jetbrains.edu.learning.StudyUtils;
|
||||
import com.jetbrains.edu.learning.course.CourseInfo;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
@@ -33,12 +33,12 @@ public class StudyNewProjectPanel{
|
||||
private JLabel myAuthorLabel;
|
||||
private JLabel myDescriptionLabel;
|
||||
private JLabel myLabel;
|
||||
private final StudyDirectoryProjectGenerator myGenerator;
|
||||
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";
|
||||
private FacetValidatorsManager myValidationManager;
|
||||
|
||||
public StudyNewProjectPanel(StudyDirectoryProjectGenerator generator) {
|
||||
public StudyNewProjectPanel(StudyProjectGenerator generator) {
|
||||
myGenerator = generator;
|
||||
Map<CourseInfo, File> courses = myGenerator.getCourses();
|
||||
if (courses.isEmpty()) {
|
||||
@@ -110,14 +110,14 @@ public class StudyNewProjectPanel{
|
||||
}
|
||||
|
||||
private void setError(String errorMessage) {
|
||||
myGenerator.setValidationResult(new ValidationResult(errorMessage));
|
||||
myGenerator.fireStateChanged(new ValidationResult(errorMessage));
|
||||
if (myValidationManager != null) {
|
||||
myValidationManager.validate();
|
||||
}
|
||||
}
|
||||
|
||||
private void setOK() {
|
||||
myGenerator.setValidationResult(ValidationResult.OK);
|
||||
myGenerator.fireStateChanged(ValidationResult.OK);
|
||||
if (myValidationManager != null) {
|
||||
myValidationManager.validate();
|
||||
}
|
||||
@@ -196,4 +196,5 @@ public class StudyNewProjectPanel{
|
||||
setOK();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.jetbrains.python.edu.ui;
|
||||
package com.jetbrains.edu.learning.ui;
|
||||
|
||||
import com.intellij.openapi.project.DumbAware;
|
||||
import com.intellij.openapi.ui.GraphicsConfig;
|
||||
@@ -1,9 +1,9 @@
|
||||
package com.jetbrains.python.edu.ui;
|
||||
package com.jetbrains.edu.learning.ui;
|
||||
|
||||
import com.intellij.ui.DocumentAdapter;
|
||||
import com.intellij.ui.components.JBScrollPane;
|
||||
import com.jetbrains.edu.learning.course.UserTest;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import com.jetbrains.python.edu.course.UserTest;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.DocumentEvent;
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.jetbrains.python.edu.ui;
|
||||
package com.jetbrains.edu.learning.ui;
|
||||
|
||||
import com.intellij.openapi.project.DumbAware;
|
||||
import com.intellij.openapi.project.Project;
|
||||
@@ -8,11 +8,11 @@ import com.intellij.ui.JBColor;
|
||||
import com.intellij.ui.content.Content;
|
||||
import com.intellij.ui.content.ContentFactory;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import com.jetbrains.python.edu.StudyTaskManager;
|
||||
import com.jetbrains.python.edu.course.Course;
|
||||
import com.jetbrains.python.edu.course.Lesson;
|
||||
import com.jetbrains.python.edu.course.LessonInfo;
|
||||
import com.jetbrains.python.edu.course.StudyStatus;
|
||||
import com.jetbrains.edu.learning.StudyTaskManager;
|
||||
import com.jetbrains.edu.learning.course.Course;
|
||||
import com.jetbrains.edu.learning.course.Lesson;
|
||||
import com.jetbrains.edu.learning.course.LessonInfo;
|
||||
import com.jetbrains.edu.learning.course.StudyStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||