hide and make visible from prev subtasks actions
[idea/community.git] / python / educational-core / student / src / com / jetbrains / edu / learning / StudyTaskManager.java
1 package com.jetbrains.edu.learning;
2
3 import com.intellij.openapi.components.PersistentStateComponent;
4 import com.intellij.openapi.components.ServiceManager;
5 import com.intellij.openapi.components.State;
6 import com.intellij.openapi.components.Storage;
7 import com.intellij.openapi.diagnostic.Logger;
8 import com.intellij.openapi.project.DumbAware;
9 import com.intellij.openapi.project.Project;
10 import com.intellij.ui.JBColor;
11 import com.intellij.util.containers.hash.HashMap;
12 import com.intellij.util.xmlb.XmlSerializer;
13 import com.intellij.util.xmlb.annotations.Transient;
14 import com.jetbrains.edu.learning.courseFormat.*;
15 import com.jetbrains.edu.learning.courseGeneration.StudyProjectGenerator;
16 import com.jetbrains.edu.learning.stepic.StepicUser;
17 import com.jetbrains.edu.learning.ui.StudyToolWindow;
18 import org.jdom.Element;
19 import org.jdom.output.XMLOutputter;
20 import org.jetbrains.annotations.NotNull;
21 import org.jetbrains.annotations.Nullable;
22
23 import java.io.File;
24 import java.util.ArrayList;
25 import java.util.Collections;
26 import java.util.List;
27 import java.util.Map;
28
29 /**
30  * Implementation of class which contains all the information
31  * about study in context of current project
32  */
33
34 @State(name = "StudySettings", storages = @Storage("study_project.xml"))
35 public class StudyTaskManager implements PersistentStateComponent<Element>, DumbAware {
36   private static final Logger LOG = Logger.getInstance(StudyTaskManager.class);
37   public static final int CURRENT_VERSION = 3;
38   private StepicUser myUser = new StepicUser();
39   private Course myCourse;
40   public int VERSION = 3;
41
42   public Map<Task, List<UserTest>> myUserTests = new HashMap<>();
43   public List<String> myInvisibleFiles = new ArrayList<>();
44
45   public boolean myShouldUseJavaFx = StudyUtils.hasJavaFx();
46   private StudyToolWindow.StudyToolWindowMode myToolWindowMode = StudyToolWindow.StudyToolWindowMode.TEXT;
47   private boolean myTurnEditingMode = false;
48   private boolean myEnableTestingFromSamples = true;
49
50   @Transient private final Project myProject;
51
52   public StudyTaskManager(Project project) {
53     myProject = project;
54   }
55
56   public StudyTaskManager() {
57     this(null);
58   }
59
60   public void setCourse(Course course) {
61     myCourse = course;
62   }
63
64   @Nullable
65   public Course getCourse() {
66     return myCourse;
67   }
68
69   public void setStatus(AnswerPlaceholder placeholder, StudyStatus status) {
70     placeholder.setStatus(status);
71   }
72
73   public void addUserTest(@NotNull final Task task, UserTest userTest) {
74     List<UserTest> userTests = myUserTests.get(task);
75     if (userTests == null) {
76       userTests = new ArrayList<>();
77       myUserTests.put(task, userTests);
78     }
79     userTests.add(userTest);
80   }
81
82   public void setUserTests(@NotNull final Task task, @NotNull final List<UserTest> userTests) {
83     myUserTests.put(task, userTests);
84   }
85
86   @NotNull
87   public List<UserTest> getUserTests(@NotNull final Task task) {
88     final List<UserTest> userTests = myUserTests.get(task);
89     return userTests != null ? userTests : Collections.emptyList();
90   }
91
92   public void removeUserTest(@NotNull final Task task, @NotNull final UserTest userTest) {
93     final List<UserTest> userTests = myUserTests.get(task);
94     if (userTests != null) {
95       userTests.remove(userTest);
96     }
97   }
98
99   public JBColor getColor(@NotNull final AnswerPlaceholder placeholder) {
100     if (!placeholder.getUseLength() && placeholder.isActive() && placeholder.getActiveSubtaskInfo().isNeedInsertText()) {
101       return JBColor.LIGHT_GRAY;
102     }
103     final StudyStatus status = placeholder.getStatus();
104     if (status == StudyStatus.Solved) {
105       return JBColor.GREEN;
106     }
107     if (status == StudyStatus.Failed) {
108       return JBColor.RED;
109     }
110     return JBColor.BLUE;
111   }
112
113   public boolean hasFailedAnswerPlaceholders(@NotNull final TaskFile taskFile) {
114     return taskFile.getActivePlaceholders().size() > 0 && taskFile.hasFailedPlaceholders();
115   }
116
117   @Nullable
118   @Override
119   public Element getState() {
120     if (myCourse == null) {
121       return null;
122     }
123     Element el = new Element("taskManager");
124     Element courseElement = new Element(StudySerializationUtils.Xml.MAIN_ELEMENT);
125     XmlSerializer.serializeInto(this, courseElement);
126     el.addContent(courseElement);
127     return el;
128   }
129
130   @Override
131   public void loadState(Element state) {
132     try {
133       int version = StudySerializationUtils.Xml.getVersion(state);
134       if (version == -1) {
135         LOG.error("StudyTaskManager doesn't contain any version:\n" + state.getValue());
136         return;
137       }
138       switch (version) {
139         case 1:
140           state = StudySerializationUtils.Xml.convertToSecondVersion(state);
141         case 2:
142           state = StudySerializationUtils.Xml.convertToThirdVersion(state, myProject);
143           //uncomment for future versions
144           //case 3:
145           //state = StudySerializationUtils.Xml.convertToForthVersion(state, myProject);
146       }
147       XmlSerializer.deserializeInto(this, state.getChild(StudySerializationUtils.Xml.MAIN_ELEMENT));
148       VERSION = CURRENT_VERSION;
149       if (myCourse != null) {
150         myCourse.initCourse(true);
151         if (version != VERSION) {
152           final File updatedCourse = new File(StudyProjectGenerator.OUR_COURSES_DIR, myCourse.getName());
153           if (updatedCourse.exists()) {
154             myCourse.setCourseDirectory(updatedCourse.getAbsolutePath());
155           }
156         }
157       }
158     }
159     catch (StudySerializationUtils.StudyUnrecognizedFormatException e) {
160       LOG.error("Unexpected course format:\n", new XMLOutputter().outputString(state));
161     }
162   }
163
164   public static StudyTaskManager getInstance(@NotNull final Project project) {
165     return ServiceManager.getService(project, StudyTaskManager.class);
166   }
167
168   public void addInvisibleFiles(String filePath) {
169     myInvisibleFiles.add(filePath);
170   }
171
172   public boolean isInvisibleFile(String path) {
173     return myInvisibleFiles.contains(path);
174   }
175
176   public boolean shouldUseJavaFx() {
177     return myShouldUseJavaFx;
178   }
179
180   public void setShouldUseJavaFx(boolean shouldUseJavaFx) {
181     this.myShouldUseJavaFx = shouldUseJavaFx;
182   }
183
184   public StudyToolWindow.StudyToolWindowMode getToolWindowMode() {
185     return myToolWindowMode;
186   }
187
188   public void setToolWindowMode(StudyToolWindow.StudyToolWindowMode toolWindowMode) {
189     myToolWindowMode = toolWindowMode;
190   }
191
192   public boolean isTurnEditingMode() {
193     return myTurnEditingMode;
194   }
195
196   public void setTurnEditingMode(boolean turnEditingMode) {
197     myTurnEditingMode = turnEditingMode;
198   }
199   
200   @NotNull
201   public StepicUser getUser() {
202     return myUser;
203   }
204
205   public void setUser(@NotNull final StepicUser user) {
206     myUser = user;
207   }
208
209   public boolean isEnableTestingFromSamples() {
210     return myEnableTestingFromSamples;
211   }
212
213   public void setEnableTestingFromSamples(boolean enableTestingFromSamples) {
214     myEnableTestingFromSamples = enableTestingFromSamples;
215   }
216 }