create course archive for subtasks
[idea/community.git] / python / educational-core / student / src / com / jetbrains / edu / learning / StudySubtaskUtils.java
1 package com.jetbrains.edu.learning;
2
3 import com.intellij.ide.projectView.ProjectView;
4 import com.intellij.openapi.editor.Document;
5 import com.intellij.openapi.fileEditor.FileDocumentManager;
6 import com.intellij.openapi.project.Project;
7 import com.intellij.openapi.vfs.VirtualFile;
8 import com.intellij.ui.EditorNotifications;
9 import com.intellij.util.containers.ContainerUtil;
10 import com.jetbrains.edu.learning.checker.StudyCheckUtils;
11 import com.jetbrains.edu.learning.core.EduNames;
12 import com.jetbrains.edu.learning.core.EduUtils;
13 import com.jetbrains.edu.learning.courseFormat.AnswerPlaceholder;
14 import com.jetbrains.edu.learning.courseFormat.AnswerPlaceholderSubtaskInfo;
15 import com.jetbrains.edu.learning.courseFormat.Task;
16 import com.jetbrains.edu.learning.courseFormat.TaskFile;
17 import com.jetbrains.edu.learning.ui.StudyToolWindow;
18 import org.jetbrains.annotations.NotNull;
19
20 import java.util.*;
21
22 public class StudySubtaskUtils {
23   private StudySubtaskUtils() {
24   }
25
26   /***
27    * @param toSubtaskIndex from 0 to subtaskNum - 1
28    */
29   public static void switchStep(@NotNull Project project, @NotNull Task task, int toSubtaskIndex) {
30     if (toSubtaskIndex == task.getActiveSubtaskIndex()) {
31       return;
32     }
33     VirtualFile taskDir = task.getTaskDir(project);
34     if (taskDir == null) {
35       return;
36     }
37     VirtualFile srcDir = taskDir.findChild(EduNames.SRC);
38     if (srcDir != null) {
39       taskDir = srcDir;
40     }
41     int fromSubtaskIndex = task.getActiveSubtaskIndex();
42     for (Map.Entry<String, TaskFile> entry : task.getTaskFiles().entrySet()) {
43       String name = entry.getKey();
44       VirtualFile virtualFile = taskDir.findChild(name);
45       if (virtualFile == null) {
46         continue;
47       }
48       TaskFile taskFile = entry.getValue();
49       Document document = FileDocumentManager.getInstance().getDocument(virtualFile);
50       if (document == null) {
51         continue;
52       }
53       updatePlaceholderTexts(project, document, taskFile, fromSubtaskIndex, toSubtaskIndex);
54       EditorNotifications.getInstance(project).updateNotifications(virtualFile);
55     }
56     task.setActiveSubtaskIndex(toSubtaskIndex);
57     update(project, task, taskDir);
58   }
59
60   private static void update(@NotNull Project project, @NotNull Task task, VirtualFile taskDir) {
61     StudyCheckUtils.drawAllPlaceholders(project, task, taskDir);
62     ProjectView.getInstance(project).refresh();
63     StudyToolWindow toolWindow = StudyUtils.getStudyToolWindow(project);
64     if (toolWindow != null) {
65       String text = StudyUtils.getTaskTextFromTask(taskDir, task);
66       if (text == null) {
67         toolWindow.setEmptyText(project);
68         return;
69       }
70       toolWindow.setTaskText(text, taskDir, project);
71     }
72   }
73
74   public static void updatePlaceholderTexts(@NotNull Project project,
75                                              @NotNull Document document,
76                                              @NotNull TaskFile taskFile,
77                                              int fromSubtaskIndex,
78                                              int toSubtaskIndex) {
79     taskFile.setTrackLengths(false);
80     for (AnswerPlaceholder placeholder : taskFile.getAnswerPlaceholders()) {
81       AnswerPlaceholderSubtaskInfo fromSubtaskInfo = placeholder.getSubtaskInfos().get(fromSubtaskIndex);
82       if (fromSubtaskIndex == toSubtaskIndex && fromSubtaskInfo != null) {
83         String placeholderText = fromSubtaskInfo.getPlaceholderText();
84         if (placeholderText != null) {
85           EduUtils.replaceAnswerPlaceholder(project, document, placeholder, placeholder.getRealLength(), placeholderText);
86         }
87         continue;
88       }
89       Set<Integer> indexes = placeholder.getSubtaskInfos().keySet();
90       Integer minIndex = Collections.min(indexes);
91       int visibleLength = placeholder.getVisibleLength(fromSubtaskIndex);
92       if (indexes.contains(toSubtaskIndex) && indexes.contains(fromSubtaskIndex)) {
93         if (!placeholder.getUseLength()) {
94           String replacementText = placeholder.getSubtaskInfos().get(toSubtaskIndex).getPossibleAnswer();
95           EduUtils.replaceAnswerPlaceholder(project, document, placeholder, visibleLength, replacementText);
96         }
97         continue;
98       }
99       if (fromSubtaskIndex < toSubtaskIndex) {
100         if (minIndex > fromSubtaskIndex && minIndex <= toSubtaskIndex) {
101           Integer maxIndex = Collections.max(ContainerUtil.filter(indexes, integer -> integer <= toSubtaskIndex));
102           AnswerPlaceholderSubtaskInfo maxInfo = placeholder.getSubtaskInfos().get(maxIndex);
103           String replacementText = placeholder.getUseLength() ? maxInfo.getPlaceholderText() : maxInfo.getPossibleAnswer();
104           EduUtils.replaceAnswerPlaceholder(project, document, placeholder, visibleLength, replacementText);
105         }
106       }
107       else {
108         if (minIndex > toSubtaskIndex && minIndex <= fromSubtaskIndex) {
109           AnswerPlaceholderSubtaskInfo minInfo = placeholder.getSubtaskInfos().get(minIndex);
110           if (minInfo.isNeedInsertText()) {
111             EduUtils.replaceAnswerPlaceholder(project, document, placeholder, visibleLength, "");
112           }
113           else {
114             String replacementText = minInfo.getPlaceholderText();
115             EduUtils.replaceAnswerPlaceholder(project, document, placeholder, visibleLength, replacementText);
116           }
117         }
118       }
119     }
120     taskFile.setTrackLengths(true);
121   }
122 }