fixed bugs after huge refactoring
[idea/community.git] / python / educational / interactive-learning / src / com / jetbrains / edu / learning / StudyUtils.java
1 package com.jetbrains.edu.learning;
2
3 import com.intellij.execution.RunContentExecutor;
4 import com.intellij.execution.configurations.GeneralCommandLine;
5 import com.intellij.execution.process.ProcessHandler;
6 import com.intellij.lang.Language;
7 import com.intellij.openapi.actionSystem.AnActionEvent;
8 import com.intellij.openapi.actionSystem.Presentation;
9 import com.intellij.openapi.diagnostic.Logger;
10 import com.intellij.openapi.editor.Document;
11 import com.intellij.openapi.editor.Editor;
12 import com.intellij.openapi.editor.actionSystem.EditorActionManager;
13 import com.intellij.openapi.editor.colors.EditorColors;
14 import com.intellij.openapi.fileEditor.FileEditor;
15 import com.intellij.openapi.fileEditor.FileEditorManager;
16 import com.intellij.openapi.project.Project;
17 import com.intellij.openapi.projectRoots.Sdk;
18 import com.intellij.openapi.ui.popup.Balloon;
19 import com.intellij.openapi.util.Disposer;
20 import com.intellij.openapi.util.io.FileUtil;
21 import com.intellij.openapi.vfs.VirtualFile;
22 import com.intellij.openapi.wm.ToolWindowManager;
23 import com.intellij.ui.JBColor;
24 import com.intellij.util.ui.UIUtil;
25 import com.jetbrains.edu.EduAnswerPlaceholderDeleteHandler;
26 import com.jetbrains.edu.EduAnswerPlaceholderPainter;
27 import com.jetbrains.edu.EduNames;
28 import com.jetbrains.edu.EduUtils;
29 import com.jetbrains.edu.courseFormat.*;
30 import com.jetbrains.edu.learning.editor.StudyEditor;
31 import com.jetbrains.edu.learning.run.StudyExecutor;
32 import com.jetbrains.edu.learning.run.StudyTestRunner;
33 import com.jetbrains.edu.learning.ui.StudyToolWindowFactory;
34 import org.jetbrains.annotations.NotNull;
35 import org.jetbrains.annotations.Nullable;
36
37 import javax.swing.*;
38 import java.io.*;
39 import java.util.Collection;
40 import java.util.List;
41
42 public class StudyUtils {
43   private StudyUtils() {
44   }
45
46   private static final Logger LOG = Logger.getInstance(StudyUtils.class.getName());
47
48   public static void closeSilently(@Nullable final Closeable stream) {
49     if (stream != null) {
50       try {
51         stream.close();
52       }
53       catch (IOException e) {
54         // close silently
55       }
56     }
57   }
58
59   public static <T> T getFirst(@NotNull final Iterable<T> container) {
60     return container.iterator().next();
61   }
62
63   public static boolean indexIsValid(int index, @NotNull final Collection collection) {
64     int size = collection.size();
65     return index >= 0 && index < size;
66   }
67
68   @SuppressWarnings("IOResourceOpenedButNotSafelyClosed")
69   @Nullable
70   public static String getFileText(@Nullable final String parentDir, @NotNull final String fileName, boolean wrapHTML,
71                                    @NotNull final String encoding) {
72     final File inputFile = parentDir != null ? new File(parentDir, fileName) : new File(fileName);
73     if (!inputFile.exists()) return null;
74     final StringBuilder taskText = new StringBuilder();
75     BufferedReader reader = null;
76     try {
77       reader = new BufferedReader(new InputStreamReader(new FileInputStream(inputFile), encoding));
78       String line;
79       while ((line = reader.readLine()) != null) {
80         taskText.append(line).append("\n");
81         if (wrapHTML) {
82           taskText.append("<br>");
83         }
84       }
85       return wrapHTML ? UIUtil.toHtml(taskText.toString()) : taskText.toString();
86     }
87     catch (IOException e) {
88       LOG.info("Failed to get file text from file " + fileName, e);
89     }
90     finally {
91       closeSilently(reader);
92     }
93     return null;
94   }
95
96   public static void updateAction(@NotNull final AnActionEvent e) {
97     final Presentation presentation = e.getPresentation();
98     presentation.setEnabled(false);
99     presentation.setVisible(false);
100     final Project project = e.getProject();
101     if (project != null) {
102       final FileEditor[] editors = FileEditorManager.getInstance(project).getAllEditors();
103       for (FileEditor editor : editors) {
104         if (editor instanceof StudyEditor) {
105           presentation.setEnabled(true);
106           presentation.setVisible(true);
107         }
108       }
109     }
110   }
111
112   public static void updateStudyToolWindow(@NotNull final Project project) {
113     ToolWindowManager.getInstance(project).getToolWindow(StudyToolWindowFactory.STUDY_TOOL_WINDOW).
114       getContentManager().removeAllContents(false);
115     StudyToolWindowFactory factory = new StudyToolWindowFactory();
116     factory.createToolWindowContent(project, ToolWindowManager.getInstance(project).
117       getToolWindow(StudyToolWindowFactory.STUDY_TOOL_WINDOW));
118   }
119
120   public static void deleteFile(@NotNull final VirtualFile file) {
121     try {
122       file.delete(StudyUtils.class);
123     }
124     catch (IOException e) {
125       LOG.error(e);
126     }
127   }
128
129   public static File copyResourceFile(@NotNull final String sourceName, @NotNull final String copyName, @NotNull final Project project,
130                                       @NotNull final Task task)
131     throws IOException {
132     final StudyTaskManager taskManager = StudyTaskManager.getInstance(project);
133     final Course course = taskManager.getCourse();
134     int taskNum = task.getIndex() + 1;
135     int lessonNum = task.getLesson().getIndex();
136     assert course != null;
137     final String pathToResource = FileUtil.join(course.getCourseDirectory(), EduNames.LESSON + lessonNum, EduNames.TASK + taskNum);
138     final File resourceFile = new File(pathToResource, copyName);
139     FileUtil.copy(new File(pathToResource, sourceName), resourceFile);
140     return resourceFile;
141   }
142
143   @Nullable
144   public static Sdk findSdk(@NotNull final Task task, @NotNull final Project project) {
145     final Language language = task.getLesson().getCourse().getLanguageById();
146     return StudyExecutor.INSTANCE.forLanguage(language).findSdk(project);
147   }
148
149   @NotNull
150   public static StudyTestRunner getTestRunner(@NotNull final Task task, @NotNull final VirtualFile taskDir) {
151     final Language language = task.getLesson().getCourse().getLanguageById();
152     return StudyExecutor.INSTANCE.forLanguage(language).getTestRunner(task, taskDir);
153   }
154
155   public static RunContentExecutor getExecutor(@NotNull final Project project, @NotNull final Task currentTask,
156                                                @NotNull final ProcessHandler handler) {
157     final Language language = currentTask.getLesson().getCourse().getLanguageById();
158     return StudyExecutor.INSTANCE.forLanguage(language).getExecutor(project, handler);
159   }
160
161   public static void setCommandLineParameters(@NotNull final GeneralCommandLine cmd,
162                                               @NotNull final Project project,
163                                               @NotNull final String filePath,
164                                               @NotNull final String sdkPath,
165                                               @NotNull final Task currentTask) {
166     final Language language = currentTask.getLesson().getCourse().getLanguageById();
167     StudyExecutor.INSTANCE.forLanguage(language).setCommandLineParameters(cmd, project, filePath, sdkPath, currentTask);
168   }
169
170   public static void showNoSdkNotification(@NotNull final Task currentTask, @NotNull final Project project) {
171     final Language language = currentTask.getLesson().getCourse().getLanguageById();
172     StudyExecutor.INSTANCE.forLanguage(language).showNoSdkNotification(project);
173   }
174
175
176   /**
177    * shows pop up in the center of "check task" button in study editor
178    */
179   public static void showCheckPopUp(@NotNull final Project project, @NotNull final Balloon balloon) {
180     final StudyEditor studyEditor = StudyEditor.getSelectedStudyEditor(project);
181     assert studyEditor != null;
182     final JButton checkButton = studyEditor.getCheckButton();
183     balloon.showInCenterOf(checkButton);
184     Disposer.register(project, balloon);
185   }
186
187   /**
188    * returns language manager which contains all the information about language specific file names
189    */
190   @Nullable
191   public static StudyLanguageManager getLanguageManager(@NotNull final Course course) {
192     Language language = course.getLanguageById();
193     return language == null ? null : StudyLanguageManager.INSTANCE.forLanguage(language);
194   }
195
196   @Nullable
197   public static TaskFile getTaskFile(@NotNull final Project project, @NotNull final VirtualFile file) {
198     final Course course = StudyTaskManager.getInstance(project).getCourse();
199     if (course == null) {
200       return null;
201     }
202     final VirtualFile taskDir = file.getParent();
203     if (taskDir == null) {
204       return null;
205     }
206     final String taskDirName = taskDir.getName();
207     if (taskDirName.contains(EduNames.TASK)) {
208       final VirtualFile lessonDir = taskDir.getParent();
209       if (lessonDir != null) {
210         int lessonIndex = EduUtils.getIndex(lessonDir.getName(), EduNames.LESSON);
211         List<Lesson> lessons = course.getLessons();
212         if (!indexIsValid(lessonIndex, lessons)) {
213           return null;
214         }
215         final Lesson lesson = lessons.get(lessonIndex);
216         int taskIndex = EduUtils.getIndex(taskDirName, EduNames.TASK);
217         final List<Task> tasks = lesson.getTaskList();
218         if (!indexIsValid(taskIndex, tasks)) {
219           return null;
220         }
221         final Task task = tasks.get(taskIndex);
222         return task.getFile(file.getName());
223       }
224     }
225     return null;
226   }
227
228
229   public static void drawAllWindows(Editor editor, TaskFile taskFile) {
230     editor.getMarkupModel().removeAllHighlighters();
231     final Project project = editor.getProject();
232     if (project == null) return;
233     final StudyTaskManager taskManager = StudyTaskManager.getInstance(project);
234     for (AnswerPlaceholder answerPlaceholder : taskFile.getAnswerPlaceholders()) {
235       final JBColor color = taskManager.getColor(answerPlaceholder);
236       EduAnswerPlaceholderPainter.drawAnswerPlaceholder(editor, answerPlaceholder, true, color);
237     }
238     final Document document = editor.getDocument();
239     EditorActionManager.getInstance()
240       .setReadonlyFragmentModificationHandler(document, new EduAnswerPlaceholderDeleteHandler(editor));
241     EduAnswerPlaceholderPainter.createGuardedBlocks(editor, taskFile, true);
242     editor.getColorsScheme().setColor(EditorColors.READONLY_FRAGMENT_BACKGROUND_COLOR, null);
243   }
244
245 }