623d648e27ec26fc91344b36aa7cbc3daa168fcd
[idea/community.git] / python / educational-core / student / src / com / jetbrains / edu / learning / projectView / StudyDirectoryNode.java
1 package com.jetbrains.edu.learning.projectView;
2
3 import com.intellij.ide.projectView.PresentationData;
4 import com.intellij.ide.projectView.ProjectView;
5 import com.intellij.ide.projectView.ViewSettings;
6 import com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode;
7 import com.intellij.openapi.fileEditor.FileEditorManager;
8 import com.intellij.openapi.project.Project;
9 import com.intellij.openapi.vfs.VirtualFile;
10 import com.intellij.psi.PsiDirectory;
11 import com.intellij.psi.PsiElement;
12 import com.intellij.ui.JBColor;
13 import com.intellij.ui.SimpleTextAttributes;
14 import com.jetbrains.edu.learning.StudyTaskManager;
15 import com.jetbrains.edu.learning.StudyUtils;
16 import com.jetbrains.edu.learning.core.EduNames;
17 import com.jetbrains.edu.learning.core.EduUtils;
18 import com.jetbrains.edu.learning.courseFormat.*;
19 import icons.InteractiveLearningIcons;
20 import org.jetbrains.annotations.NotNull;
21
22 import javax.swing.*;
23 import java.awt.*;
24 import java.util.Map;
25
26 public class StudyDirectoryNode extends PsiDirectoryNode {
27   public static final JBColor LIGHT_GREEN = new JBColor(new Color(0, 134, 0), new Color(98, 150, 85));
28   protected final PsiDirectory myValue;
29   protected final Project myProject;
30
31   public StudyDirectoryNode(@NotNull final Project project,
32                             PsiDirectory value,
33                             ViewSettings viewSettings) {
34     super(project, value, viewSettings);
35     myValue = value;
36     myProject = project;
37   }
38
39   @Override
40   protected void updateImpl(PresentationData data) {
41     String valueName = myValue.getName();
42     StudyTaskManager studyTaskManager = StudyTaskManager.getInstance(myProject);
43     Course course = studyTaskManager.getCourse();
44     if (course == null) {
45       return;
46     }
47     if (valueName.equals(myProject.getBaseDir().getName())) {
48       data.clearText();
49       data.setIcon(InteractiveLearningIcons.Course);
50       data.addText(course.getName(), new SimpleTextAttributes(SimpleTextAttributes.STYLE_PLAIN, JBColor.BLACK));
51     }
52     else if (valueName.contains(EduNames.TASK)) {
53       VirtualFile taskVirtualFile = myValue.getVirtualFile();
54       VirtualFile lessonVirtualFile = taskVirtualFile.getParent();
55       if (lessonVirtualFile != null) {
56         Lesson lesson = course.getLesson(lessonVirtualFile.getName());
57         if (lesson != null) {
58           Task task = lesson.getTask(taskVirtualFile.getName());
59           if (task != null) {
60             setStudyAttributes(task, data, task.getName());
61           }
62         }
63       }
64     }
65     else if (valueName.contains(EduNames.LESSON)) {
66       int lessonIndex = Integer.parseInt(valueName.substring(EduNames.LESSON.length())) - 1;
67       Lesson lesson = course.getLessons().get(lessonIndex);
68       setStudyAttributes(lesson, data, lesson.getName());
69       data.setPresentableText(valueName);
70     }
71     else if (valueName.contains(EduNames.SANDBOX_DIR)) {
72       if (myValue.getParent() != null) {
73         final String parentName = myValue.getParent().getName();
74         if (!parentName.contains(EduNames.SANDBOX_DIR)) {
75           data.setPresentableText(EduNames.SANDBOX_DIR);
76           data.setIcon(InteractiveLearningIcons.Sandbox);
77         }
78       }
79     }
80     data.setPresentableText(valueName);
81   }
82
83   @Override
84   public int getTypeSortWeight(boolean sortByType) {
85     String name = myValue.getName();
86     if (name.contains(EduNames.LESSON) || name.contains(EduNames.TASK)) {
87       String logicalName = name.contains(EduNames.LESSON) ? EduNames.LESSON : EduNames.TASK;
88       return EduUtils.getIndex(name, logicalName) + 1;
89     }
90     return name.contains(EduNames.SANDBOX_DIR) ? 0 : 3;
91   }
92
93   private static void setStudyAttributes(Lesson lesson, PresentationData data, String additionalName) {
94     switch (lesson.getStatus()) {
95       case Unchecked: {
96         updatePresentation(data, additionalName, JBColor.BLACK, InteractiveLearningIcons.Lesson);
97         break;
98       }
99       case Solved: {
100         updatePresentation(data, additionalName, LIGHT_GREEN, InteractiveLearningIcons.LessonCompl);
101         break;
102       }
103       case Failed: {
104         updatePresentation(data, additionalName, JBColor.RED, InteractiveLearningIcons.Lesson);
105       }
106     }
107   }
108
109   protected void setStudyAttributes(Task task, PresentationData data, String name) {
110     StudyStatus taskStatus = task.getStatus();
111     switch (taskStatus) {
112       case Unchecked: {
113         updatePresentation(data, name, JBColor.BLACK, InteractiveLearningIcons.Task);
114         break;
115       }
116       case Solved: {
117         updatePresentation(data, name, LIGHT_GREEN, InteractiveLearningIcons.TaskCompl);
118         break;
119       }
120       case Failed: {
121         updatePresentation(data, name, JBColor.RED, InteractiveLearningIcons.TaskProbl);
122       }
123     }
124   }
125
126   protected static void updatePresentation(PresentationData data, String name, JBColor color, Icon icon) {
127     data.clearText();
128     data.addText(name, new SimpleTextAttributes(SimpleTextAttributes.STYLE_PLAIN, color));
129     data.setIcon(icon);
130   }
131
132   @Override
133   public boolean canNavigate() {
134     return true;
135   }
136
137   @Override
138   public boolean canNavigateToSource() {
139     return true;
140   }
141
142   @Override
143   public void navigate(boolean requestFocus) {
144     final String myValueName = myValue.getName();
145     if (myValueName.contains(EduNames.TASK)) {
146       TaskFile taskFile = null;
147       VirtualFile virtualFile =  null;
148       for (PsiElement child : myValue.getChildren()) {
149         VirtualFile childFile = child.getContainingFile().getVirtualFile();
150         taskFile = StudyUtils.getTaskFile(myProject, childFile);
151         if (taskFile != null) {
152           virtualFile = childFile;
153           break;
154         }
155       }
156       if (taskFile != null) {
157         VirtualFile taskDir = virtualFile.getParent();
158         Task task = taskFile.getTask();
159         for (VirtualFile openFile : FileEditorManager.getInstance(myProject).getOpenFiles()) {
160           FileEditorManager.getInstance(myProject).closeFile(openFile);
161         }
162         VirtualFile child = null;
163         for (Map.Entry<String, TaskFile> entry: task.getTaskFiles().entrySet()) {
164           VirtualFile file = taskDir.findChild(entry.getKey());
165           if (file != null) {
166             FileEditorManager.getInstance(myProject).openFile(file, true);
167           }
168           if (!entry.getValue().getActivePlaceholders().isEmpty()) {
169             child = file;
170           }
171         }
172         if (child != null) {
173           ProjectView.getInstance(myProject).select(child, child, false);
174           FileEditorManager.getInstance(myProject).openFile(child, true);
175         } else {
176           VirtualFile[] children = taskDir.getChildren();
177           if (children.length > 0) {
178             ProjectView.getInstance(myProject).select(children[0], children[0], false);
179           }
180         }
181       }
182     }
183   }
184
185   @Override
186   public boolean expandOnDoubleClick() {
187     final String myValueName = myValue.getName();
188     if (myValueName.contains(EduNames.TASK)) {
189       return false;
190     }
191     return super.expandOnDoubleClick();
192   }
193
194   @Override
195   protected boolean hasProblemFileBeneath() {
196     return false;
197   }
198
199   @Override
200   public String getNavigateActionText(boolean focusEditor) {
201     return null;
202   }
203 }