EDU-407 Files created by user code are invisible
[idea/community.git] / python / educational / interactive-learning / src / com / jetbrains / edu / learning / StudyTaskManager.java
1 package com.jetbrains.edu.learning;
2
3 import com.intellij.openapi.components.*;
4 import com.intellij.openapi.project.DumbAware;
5 import com.intellij.openapi.project.Project;
6 import com.intellij.ui.JBColor;
7 import com.intellij.util.containers.hash.HashMap;
8 import com.intellij.util.xmlb.XmlSerializerUtil;
9 import com.jetbrains.edu.courseFormat.*;
10 import com.jetbrains.edu.learning.courseFormat.StudyStatus;
11 import com.jetbrains.edu.learning.courseFormat.UserTest;
12 import org.jetbrains.annotations.NotNull;
13 import org.jetbrains.annotations.Nullable;
14
15 import java.util.ArrayList;
16 import java.util.Collections;
17 import java.util.List;
18 import java.util.Map;
19
20 /**
21  * Implementation of class which contains all the information
22  * about study in context of current project
23  */
24
25 @State(
26   name = "StudySettings",
27   storages = {
28     @Storage(file = StoragePathMacros.PROJECT_FILE),
29     @Storage(
30       file = StoragePathMacros.PROJECT_CONFIG_DIR + "/study_project.xml",
31       scheme = StorageScheme.DIRECTORY_BASED
32     )}
33 )
34 public class StudyTaskManager implements PersistentStateComponent<StudyTaskManager>, DumbAware {
35   private Course myCourse;
36   public Map<AnswerPlaceholder, StudyStatus> myStudyStatusMap = new HashMap<AnswerPlaceholder, StudyStatus>();
37   public Map<TaskFile, StudyStatus> myTaskStatusMap = new HashMap<TaskFile, StudyStatus>();
38   public Map<Task, List<UserTest>> myUserTests = new HashMap<Task, List<UserTest>>();
39   public List<String> myInvisibleFiles = new ArrayList<String>();
40
41   private StudyTaskManager() {
42   }
43
44   public void setCourse(@NotNull final Course course) {
45     myCourse = course;
46   }
47
48   @Nullable
49   public Course getCourse() {
50     return myCourse;
51   }
52
53   public void setStatus(AnswerPlaceholder placeholder, StudyStatus status) {
54     if (myStudyStatusMap == null) {
55       myStudyStatusMap = new HashMap<AnswerPlaceholder, StudyStatus>();
56     }
57     myStudyStatusMap.put(placeholder, status);
58   }
59
60   public void addUserTest(@NotNull final Task task, UserTest userTest) {
61     List<UserTest> userTests = myUserTests.get(task);
62     if (userTests == null) {
63       userTests = new ArrayList<UserTest>();
64       myUserTests.put(task, userTests);
65     }
66     userTests.add(userTest);
67   }
68
69   public void setUserTests(@NotNull final Task task, @NotNull final List<UserTest> userTests) {
70     myUserTests.put(task, userTests);
71   }
72
73   @NotNull
74   public List<UserTest> getUserTests(@NotNull final Task task) {
75     final List<UserTest> userTests = myUserTests.get(task);
76     return userTests != null ? userTests : Collections.<UserTest>emptyList();
77   }
78
79   public void removeUserTest(@NotNull final Task task, @NotNull final UserTest userTest) {
80     final List<UserTest> userTests = myUserTests.get(task);
81     if (userTests != null) {
82       userTests.remove(userTest);
83     }
84   }
85
86
87   public void setStatus(Task task, StudyStatus status) {
88     for (TaskFile taskFile : task.getTaskFiles().values()) {
89       setStatus(taskFile, status);
90     }
91   }
92
93   public void setStatus(TaskFile file, StudyStatus status) {
94     if (file.getAnswerPlaceholders().isEmpty()) {
95       if (myTaskStatusMap == null) {
96         myTaskStatusMap = new HashMap<TaskFile, StudyStatus>();
97       }
98       myTaskStatusMap.put(file, status);
99     }
100     for (AnswerPlaceholder answerPlaceholder : file.getAnswerPlaceholders()) {
101       setStatus(answerPlaceholder, status);
102     }
103   }
104
105   public StudyStatus getStatus(AnswerPlaceholder placeholder) {
106     StudyStatus status = myStudyStatusMap.get(placeholder);
107     if (status == null) {
108       status = StudyStatus.Unchecked;
109       myStudyStatusMap.put(placeholder, status);
110     }
111     return status;
112   }
113
114
115   public StudyStatus getStatus(@NotNull final Lesson lesson) {
116     for (Task task : lesson.getTaskList()) {
117       StudyStatus taskStatus = getStatus(task);
118       if (taskStatus == StudyStatus.Unchecked || taskStatus == StudyStatus.Failed) {
119         return StudyStatus.Unchecked;
120       }
121     }
122     return StudyStatus.Solved;
123   }
124
125   public StudyStatus getStatus(@NotNull final Task task) {
126     for (TaskFile taskFile : task.getTaskFiles().values()) {
127       StudyStatus taskFileStatus = getStatus(taskFile);
128       if (taskFileStatus == StudyStatus.Unchecked) {
129         return StudyStatus.Unchecked;
130       }
131       if (taskFileStatus == StudyStatus.Failed) {
132         return StudyStatus.Failed;
133       }
134     }
135     return StudyStatus.Solved;
136   }
137
138   private StudyStatus getStatus(@NotNull final TaskFile file) {
139     if (file.getAnswerPlaceholders().isEmpty()) {
140       if (myTaskStatusMap == null) return StudyStatus.Solved;
141       return myTaskStatusMap.get(file);
142
143     }
144     for (AnswerPlaceholder answerPlaceholder : file.getAnswerPlaceholders()) {
145       StudyStatus placeholderStatus = getStatus(answerPlaceholder);
146       if (placeholderStatus == StudyStatus.Failed) {
147         return StudyStatus.Failed;
148       }
149       if (placeholderStatus == StudyStatus.Unchecked) {
150         return StudyStatus.Unchecked;
151       }
152     }
153     return StudyStatus.Solved;
154   }
155
156
157   public JBColor getColor(@NotNull final AnswerPlaceholder placeholder) {
158     final StudyStatus status = getStatus(placeholder);
159     if (status == StudyStatus.Solved) {
160       return JBColor.GREEN;
161     }
162     if (status == StudyStatus.Failed) {
163       return JBColor.RED;
164     }
165     return JBColor.BLUE;
166   }
167
168   public boolean hasFailedAnswerPlaceholders(@NotNull final TaskFile taskFile) {
169     return taskFile.getAnswerPlaceholders().size() > 0 && getStatus(taskFile) == StudyStatus.Failed;
170   }
171   @Nullable
172   @Override
173   public StudyTaskManager getState() {
174     return this;
175   }
176
177   @Override
178   public void loadState(StudyTaskManager state) {
179     XmlSerializerUtil.copyBean(state, this);
180     if (myCourse != null) {
181       myCourse.initCourse(true);
182     }
183   }
184
185   public static StudyTaskManager getInstance(@NotNull final Project project) {
186     return ServiceManager.getService(project, StudyTaskManager.class);
187   }
188
189   public void addInvisibleFiles(String filePath) {
190     myInvisibleFiles.add(filePath);
191   }
192
193   public boolean isInvisibleFile(String path) {
194     return myInvisibleFiles.contains(path);
195   }
196 }