diff --git a/python/educational-core/src/com/jetbrains/edu/learning/checker/StudyCheckTask.java b/python/educational-core/src/com/jetbrains/edu/learning/checker/StudyCheckTask.java index 55e82678ab00..096ec8e5af8d 100644 --- a/python/educational-core/src/com/jetbrains/edu/learning/checker/StudyCheckTask.java +++ b/python/educational-core/src/com/jetbrains/edu/learning/checker/StudyCheckTask.java @@ -5,25 +5,22 @@ import com.intellij.execution.process.ProcessOutput; import com.intellij.ide.projectView.ProjectView; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.editor.Document; -import com.intellij.openapi.fileEditor.FileDocumentManager; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.MessageType; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.Ref; -import com.intellij.openapi.util.TextRange; import com.intellij.openapi.vfs.VirtualFile; -import com.jetbrains.edu.learning.*; +import com.jetbrains.edu.learning.StudySettings; +import com.jetbrains.edu.learning.StudyState; +import com.jetbrains.edu.learning.StudyTaskManager; +import com.jetbrains.edu.learning.StudyUtils; import com.jetbrains.edu.learning.core.EduNames; import com.jetbrains.edu.learning.core.EduUtils; -import com.jetbrains.edu.learning.courseFormat.AnswerPlaceholder; import com.jetbrains.edu.learning.courseFormat.Course; import com.jetbrains.edu.learning.courseFormat.StudyStatus; -import com.jetbrains.edu.learning.courseFormat.TaskFile; import com.jetbrains.edu.learning.courseFormat.tasks.ChoiceTask; import com.jetbrains.edu.learning.courseFormat.tasks.Task; -import com.jetbrains.edu.learning.courseFormat.tasks.TaskWithSubtasks; import com.jetbrains.edu.learning.courseFormat.tasks.TheoryTask; import com.jetbrains.edu.learning.stepic.EduAdaptiveStepicConnector; import com.jetbrains.edu.learning.stepic.EduStepicConnector; @@ -31,8 +28,6 @@ import com.jetbrains.edu.learning.stepic.StepicUser; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.Map; - public class StudyCheckTask extends com.intellij.openapi.progress.Task.Backgroundable { private static final Logger LOG = Logger.getInstance(StudyCheckTask.class); @@ -228,73 +223,8 @@ public class StudyCheckTask extends com.intellij.openapi.progress.Task.Backgroun } protected void onTaskSolved(@NotNull String message) { - final Course course = StudyTaskManager.getInstance(myProject).getCourse(); myTask.setStatus(StudyStatus.Solved); - if (course != null) { - if (course.isAdaptive()) { - ApplicationManager.getApplication().invokeLater( - () -> { - if (myTask instanceof ChoiceTask) { - StudyCheckUtils.showTestResultPopUp("Congratulations!", MessageType.INFO.getPopupBackground(), myProject); - } - else { - StudyCheckUtils.showTestResultPopUp("Congratulations!", MessageType.INFO.getPopupBackground(), myProject); - StudyCheckUtils.showTestResultsToolWindow(myProject, message, true); - } - }); - } - else { - if (myTask instanceof TaskWithSubtasks) { - boolean hasMoreSubtasks = ((TaskWithSubtasks)myTask).activeSubtaskNotLast(); - final int activeSubtaskIndex = ((TaskWithSubtasks)myTask).getActiveSubtaskIndex(); - int visibleSubtaskIndex = activeSubtaskIndex + 1; - - ApplicationManager.getApplication().invokeLater(() -> { - int subtaskSize = ((TaskWithSubtasks)myTask).getLastSubtaskIndex() + 1; - String resultMessage = !hasMoreSubtasks ? message : "Subtask " + visibleSubtaskIndex + "/" + subtaskSize + " solved"; - StudyCheckUtils.showTestResultPopUp(resultMessage, MessageType.INFO.getPopupBackground(), myProject); - if (hasMoreSubtasks) { - int nextSubtaskIndex = activeSubtaskIndex + 1; - StudySubtaskUtils.switchStep(myProject, (TaskWithSubtasks)myTask, nextSubtaskIndex); - rememberAnswers(nextSubtaskIndex); - } - }); - } - else { - ApplicationManager.getApplication().invokeLater( - () -> StudyCheckUtils.showTestResultPopUp(message, MessageType.INFO.getPopupBackground(), myProject)); - } - } - } - } - - private void rememberAnswers(int nextSubtaskIndex) { - VirtualFile taskDir = myTask.getTaskDir(myProject); - if (taskDir == null) { - return; - } - VirtualFile srcDir = taskDir.findChild(EduNames.SRC); - if (srcDir != null) { - taskDir = srcDir; - } - for (Map.Entry entry : myTask.getTaskFiles().entrySet()) { - TaskFile taskFile = entry.getValue(); - VirtualFile virtualFile = taskDir.findFileByRelativePath(entry.getKey()); - if (virtualFile == null) { - continue; - } - Document document = FileDocumentManager.getInstance().getDocument(virtualFile); - if (document == null) { - continue; - } - for (AnswerPlaceholder placeholder : taskFile.getActivePlaceholders()) { - if (placeholder.getSubtaskInfos().containsKey(nextSubtaskIndex - 1)) { - int offset = placeholder.getOffset(); - String answer = document.getText(TextRange.create(offset, offset + placeholder.getRealLength())); - placeholder.getSubtaskInfos().get(nextSubtaskIndex - 1).setAnswer(answer); - } - } - } + myTask.getChecker(myProject).onTaskSolved(message); } private void runAfterTaskCheckedActions() { diff --git a/python/educational-core/src/com/jetbrains/edu/learning/checker/StudyCheckUtils.java b/python/educational-core/src/com/jetbrains/edu/learning/checker/StudyCheckUtils.java index 7ba9aef911f5..a6da62dffb4e 100644 --- a/python/educational-core/src/com/jetbrains/edu/learning/checker/StudyCheckUtils.java +++ b/python/educational-core/src/com/jetbrains/edu/learning/checker/StudyCheckUtils.java @@ -108,7 +108,7 @@ public class StudyCheckUtils { } - public static void showTestResultPopUp(final String text, Color color, @NotNull final Project project) { + public static void showTestResultPopUp(@NotNull final String text, Color color, @NotNull final Project project) { BalloonBuilder balloonBuilder = JBPopupFactory.getInstance().createHtmlTextBalloonBuilder(text, null, color, null); final Balloon balloon = balloonBuilder.createBalloon(); diff --git a/python/educational-core/src/com/jetbrains/edu/learning/checker/StudyTaskChecker.java b/python/educational-core/src/com/jetbrains/edu/learning/checker/StudyTaskChecker.java new file mode 100644 index 000000000000..704cfc0b960f --- /dev/null +++ b/python/educational-core/src/com/jetbrains/edu/learning/checker/StudyTaskChecker.java @@ -0,0 +1,22 @@ +package com.jetbrains.edu.learning.checker; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.MessageType; +import com.jetbrains.edu.learning.courseFormat.tasks.Task; +import org.jetbrains.annotations.NotNull; + +public class StudyTaskChecker { + @NotNull protected final T myTask; + @NotNull protected final Project myProject; + + public StudyTaskChecker(@NotNull T task, @NotNull Project project) { + myTask = task; + myProject = project; + } + + public void onTaskSolved(@NotNull String message) { + ApplicationManager.getApplication().invokeLater( + () -> StudyCheckUtils.showTestResultPopUp(message, MessageType.INFO.getPopupBackground(), myProject)); + } +} diff --git a/python/educational-core/src/com/jetbrains/edu/learning/courseFormat/tasks/Task.java b/python/educational-core/src/com/jetbrains/edu/learning/courseFormat/tasks/Task.java index 3b6aad423338..4bfc083c656e 100644 --- a/python/educational-core/src/com/jetbrains/edu/learning/courseFormat/tasks/Task.java +++ b/python/educational-core/src/com/jetbrains/edu/learning/courseFormat/tasks/Task.java @@ -9,6 +9,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.xmlb.XmlSerializer; import com.intellij.util.xmlb.annotations.Transient; +import com.jetbrains.edu.learning.checker.StudyTaskChecker; import com.jetbrains.edu.learning.EduPluginConfigurator; import com.jetbrains.edu.learning.core.EduNames; import com.jetbrains.edu.learning.courseFormat.*; @@ -269,4 +270,8 @@ public abstract class Task implements StudyItem { // used in json serialization/deserialization public abstract String getTaskType(); + + public StudyTaskChecker getChecker(@NotNull Project project) { + return new StudyTaskChecker<>(this, project); + } } diff --git a/python/educational-core/src/com/jetbrains/edu/learning/courseFormat/tasks/TaskWithSubtasks.java b/python/educational-core/src/com/jetbrains/edu/learning/courseFormat/tasks/TaskWithSubtasks.java index ac10657b829c..63d70d5fd3f4 100644 --- a/python/educational-core/src/com/jetbrains/edu/learning/courseFormat/tasks/TaskWithSubtasks.java +++ b/python/educational-core/src/com/jetbrains/edu/learning/courseFormat/tasks/TaskWithSubtasks.java @@ -2,11 +2,24 @@ package com.jetbrains.edu.learning.courseFormat.tasks; import com.google.gson.annotations.Expose; import com.google.gson.annotations.SerializedName; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.MessageType; +import com.intellij.openapi.util.TextRange; +import com.intellij.openapi.vfs.VirtualFile; +import com.jetbrains.edu.learning.StudySubtaskUtils; +import com.jetbrains.edu.learning.checker.StudyCheckUtils; +import com.jetbrains.edu.learning.checker.StudyTaskChecker; +import com.jetbrains.edu.learning.core.EduNames; import com.jetbrains.edu.learning.courseFormat.AnswerPlaceholder; import com.jetbrains.edu.learning.courseFormat.StudyStatus; import com.jetbrains.edu.learning.courseFormat.TaskFile; import org.jetbrains.annotations.NotNull; +import java.util.Map; + public class TaskWithSubtasks extends Task { private int myActiveSubtaskIndex = 0; @SerializedName("last_subtask_index") @@ -58,4 +71,55 @@ public class TaskWithSubtasks extends Task { public String getTaskType() { return "subtasks"; } + + @Override + public StudyTaskChecker getChecker(@NotNull Project project) { + return new StudyTaskChecker(this, project) { + @Override + public void onTaskSolved(@NotNull String message) { + boolean hasMoreSubtasks = myTask.activeSubtaskNotLast(); + final int activeSubtaskIndex = myTask.getActiveSubtaskIndex(); + int visibleSubtaskIndex = activeSubtaskIndex + 1; + ApplicationManager.getApplication().invokeLater(() -> { + int subtaskSize = myTask.getLastSubtaskIndex() + 1; + String resultMessage = !hasMoreSubtasks ? message : "Subtask " + visibleSubtaskIndex + "/" + subtaskSize + " solved"; + StudyCheckUtils.showTestResultPopUp(resultMessage, MessageType.INFO.getPopupBackground(), myProject); + if (hasMoreSubtasks) { + int nextSubtaskIndex = activeSubtaskIndex + 1; + StudySubtaskUtils.switchStep(myProject, myTask, nextSubtaskIndex); + rememberAnswers(nextSubtaskIndex, myTask); + } + }); + } + + private void rememberAnswers(int nextSubtaskIndex, @NotNull TaskWithSubtasks task) { + VirtualFile taskDir = task.getTaskDir(myProject); + if (taskDir == null) { + return; + } + VirtualFile srcDir = taskDir.findChild(EduNames.SRC); + if (srcDir != null) { + taskDir = srcDir; + } + for (Map.Entry entry : task.getTaskFiles().entrySet()) { + TaskFile taskFile = entry.getValue(); + VirtualFile virtualFile = taskDir.findFileByRelativePath(entry.getKey()); + if (virtualFile == null) { + continue; + } + Document document = FileDocumentManager.getInstance().getDocument(virtualFile); + if (document == null) { + continue; + } + for (AnswerPlaceholder placeholder : taskFile.getActivePlaceholders()) { + if (placeholder.getSubtaskInfos().containsKey(nextSubtaskIndex - 1)) { + int offset = placeholder.getOffset(); + String answer = document.getText(TextRange.create(offset, offset + placeholder.getRealLength())); + placeholder.getSubtaskInfos().get(nextSubtaskIndex - 1).setAnswer(answer); + } + } + } + } + }; + } }