b6d9a71b52415de6ad32fbeda0b6ea71366273d8
[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     final StudyStatus status = placeholder.getStatus();
101     if (status == StudyStatus.Solved) {
102       return JBColor.GREEN;
103     }
104     if (status == StudyStatus.Failed) {
105       return JBColor.RED;
106     }
107     return JBColor.BLUE;
108   }
109
110   public boolean hasFailedAnswerPlaceholders(@NotNull final TaskFile taskFile) {
111     return taskFile.getActivePlaceholders().size() > 0 && taskFile.hasFailedPlaceholders();
112   }
113
114   @Nullable
115   @Override
116   public Element getState() {
117     if (myCourse == null) {
118       return null;
119     }
120     Element el = new Element("taskManager");
121     Element courseElement = new Element(StudySerializationUtils.Xml.MAIN_ELEMENT);
122     XmlSerializer.serializeInto(this, courseElement);
123     el.addContent(courseElement);
124     return el;
125   }
126
127   @Override
128   public void loadState(Element state) {
129     try {
130       int version = StudySerializationUtils.Xml.getVersion(state);
131       if (version == -1) {
132         LOG.error("StudyTaskManager doesn't contain any version:\n" + state.getValue());
133         return;
134       }
135       switch (version) {
136         case 1:
137           state = StudySerializationUtils.Xml.convertToSecondVersion(state);
138         case 2:
139           state = StudySerializationUtils.Xml.convertToThirdVersion(state, myProject);
140           //uncomment for future versions
141           //case 3:
142           //state = StudySerializationUtils.Xml.convertToForthVersion(state, myProject);
143       }
144       XmlSerializer.deserializeInto(this, state.getChild(StudySerializationUtils.Xml.MAIN_ELEMENT));
145       VERSION = CURRENT_VERSION;
146       if (myCourse != null) {
147         myCourse.initCourse(true);
148         if (version != VERSION) {
149           final File updatedCourse = new File(StudyProjectGenerator.OUR_COURSES_DIR, myCourse.getName());
150           if (updatedCourse.exists()) {
151             myCourse.setCourseDirectory(updatedCourse.getAbsolutePath());
152           }
153         }
154       }
155     }
156     catch (StudySerializationUtils.StudyUnrecognizedFormatException e) {
157       LOG.error("Unexpected course format:\n", new XMLOutputter().outputString(state));
158     }
159   }
160
161   public static StudyTaskManager getInstance(@NotNull final Project project) {
162     return ServiceManager.getService(project, StudyTaskManager.class);
163   }
164
165   public void addInvisibleFiles(String filePath) {
166     myInvisibleFiles.add(filePath);
167   }
168
169   public boolean isInvisibleFile(String path) {
170     return myInvisibleFiles.contains(path);
171   }
172
173   public boolean shouldUseJavaFx() {
174     return myShouldUseJavaFx;
175   }
176
177   public void setShouldUseJavaFx(boolean shouldUseJavaFx) {
178     this.myShouldUseJavaFx = shouldUseJavaFx;
179   }
180
181   public StudyToolWindow.StudyToolWindowMode getToolWindowMode() {
182     return myToolWindowMode;
183   }
184
185   public void setToolWindowMode(StudyToolWindow.StudyToolWindowMode toolWindowMode) {
186     myToolWindowMode = toolWindowMode;
187   }
188
189   public boolean isTurnEditingMode() {
190     return myTurnEditingMode;
191   }
192
193   public void setTurnEditingMode(boolean turnEditingMode) {
194     myTurnEditingMode = turnEditingMode;
195   }
196   
197   @NotNull
198   public StepicUser getUser() {
199     return myUser;
200   }
201
202   public void setUser(@NotNull final StepicUser user) {
203     myUser = user;
204   }
205
206   public boolean isEnableTestingFromSamples() {
207     return myEnableTestingFromSamples;
208   }
209
210   public void setEnableTestingFromSamples(boolean enableTestingFromSamples) {
211     myEnableTestingFromSamples = enableTestingFromSamples;
212   }
213 }