1 package com.jetbrains.python.edu;
3 import com.intellij.ide.SaveAndSyncHandlerImpl;
4 import com.intellij.ide.projectView.actions.MarkRootActionBase;
5 import com.intellij.openapi.actionSystem.AnActionEvent;
6 import com.intellij.openapi.actionSystem.Presentation;
7 import com.intellij.openapi.application.ApplicationManager;
8 import com.intellij.openapi.diagnostic.Logger;
9 import com.intellij.openapi.editor.Document;
10 import com.intellij.openapi.fileEditor.FileDocumentManager;
11 import com.intellij.openapi.fileEditor.FileEditor;
12 import com.intellij.openapi.fileEditor.FileEditorManager;
13 import com.intellij.openapi.module.Module;
14 import com.intellij.openapi.module.ModuleManager;
15 import com.intellij.openapi.module.ModuleUtilCore;
16 import com.intellij.openapi.project.Project;
17 import com.intellij.openapi.projectRoots.Sdk;
18 import com.intellij.openapi.roots.ContentEntry;
19 import com.intellij.openapi.roots.ModifiableRootModel;
20 import com.intellij.openapi.roots.ModuleRootManager;
21 import com.intellij.openapi.util.TextRange;
22 import com.intellij.openapi.util.io.FileUtil;
23 import com.intellij.openapi.vfs.VirtualFile;
24 import com.intellij.openapi.vfs.VirtualFileManager;
25 import com.intellij.openapi.wm.ToolWindowManager;
26 import com.intellij.util.ui.UIUtil;
27 import com.jetbrains.python.edu.course.*;
28 import com.jetbrains.python.edu.editor.StudyEditor;
29 import com.jetbrains.python.edu.ui.StudyToolWindowFactory;
30 import com.jetbrains.python.sdk.PythonSdkType;
31 import org.jetbrains.annotations.NotNull;
32 import org.jetbrains.annotations.Nullable;
35 import java.util.Collection;
37 public class StudyUtils {
38 private static final Logger LOG = Logger.getInstance(StudyUtils.class.getName());
40 public static void closeSilently(Closeable stream) {
45 catch (IOException e) {
51 public static boolean isZip(String fileName) {
52 return fileName.contains(".zip");
55 public static <T> T getFirst(Iterable<T> container) {
56 return container.iterator().next();
59 public static boolean indexIsValid(int index, Collection collection) {
60 int size = collection.size();
61 return index >= 0 && index < size;
64 @SuppressWarnings("IOResourceOpenedButNotSafelyClosed")
66 public static String getFileText(String parentDir, String fileName, boolean wrapHTML) {
68 File inputFile = parentDir != null ? new File(parentDir, fileName) : new File(fileName);
69 if (!inputFile.exists()) return null;
70 StringBuilder taskText = new StringBuilder();
71 BufferedReader reader = null;
73 reader = new BufferedReader(new InputStreamReader(new FileInputStream(inputFile)));
75 while ((line = reader.readLine()) != null) {
76 taskText.append(line).append("\n");
78 taskText.append("<br>");
81 return wrapHTML ? UIUtil.toHtml(taskText.toString()) : taskText.toString();
83 catch (IOException e) {
84 LOG.info("Failed to get file text from file " + fileName, e);
87 closeSilently(reader);
92 public static void updateAction(AnActionEvent e) {
93 Presentation presentation = e.getPresentation();
94 presentation.setEnabled(false);
95 presentation.setVisible(false);
96 Project project = e.getProject();
97 if (project != null) {
98 FileEditor[] editors = FileEditorManager.getInstance(project).getAllEditors();
99 for (FileEditor editor : editors) {
100 if (editor instanceof StudyEditor) {
101 presentation.setEnabled(true);
102 presentation.setVisible(true);
108 public static void updateStudyToolWindow(Project project) {
109 ToolWindowManager.getInstance(project).getToolWindow(StudyToolWindowFactory.STUDY_TOOL_WINDOW).getContentManager()
110 .removeAllContents(false);
111 StudyToolWindowFactory factory = new StudyToolWindowFactory();
113 .createToolWindowContent(project, ToolWindowManager.getInstance(project).getToolWindow(StudyToolWindowFactory.STUDY_TOOL_WINDOW));
116 public static void synchronize() {
117 FileDocumentManager.getInstance().saveAllDocuments();
118 SaveAndSyncHandlerImpl.refreshOpenFiles();
119 VirtualFileManager.getInstance().refreshWithoutFileWatcher(true);
123 * Gets number index in directory names like "task1", "lesson2"
125 * @param fullName full name of directory
126 * @param logicalName part of name without index
127 * @return index of object
129 public static int getIndex(@NotNull final String fullName, @NotNull final String logicalName) {
130 if (!fullName.contains(logicalName)) {
131 throw new IllegalArgumentException();
133 return Integer.parseInt(fullName.substring(logicalName.length())) - 1;
136 @SuppressWarnings("IOResourceOpenedButNotSafelyClosed")
137 public static VirtualFile flushWindows(TaskFile taskFile, VirtualFile file) {
138 VirtualFile taskDir = file.getParent();
139 VirtualFile fileWindows = null;
140 final Document document = FileDocumentManager.getInstance().getDocument(file);
141 if (document == null) {
142 LOG.debug("Couldn't flush windows");
145 if (taskDir != null) {
146 String name = file.getNameWithoutExtension() + "_windows";
147 PrintWriter printWriter = null;
149 fileWindows = taskDir.createChildData(taskFile, name);
150 printWriter = new PrintWriter(new FileOutputStream(fileWindows.getPath()));
151 for (TaskWindow taskWindow : taskFile.getTaskWindows()) {
152 if (!taskWindow.isValid(document)) {
153 printWriter.println("#educational_plugin_window = ");
156 int start = taskWindow.getRealStartOffset(document);
157 String windowDescription = document.getText(new TextRange(start, start + taskWindow.getLength()));
158 printWriter.println("#educational_plugin_window = " + windowDescription);
160 ApplicationManager.getApplication().runWriteAction(new Runnable() {
163 FileDocumentManager.getInstance().saveDocument(document);
167 catch (IOException e) {
171 closeSilently(printWriter);
178 public static void deleteFile(VirtualFile file) {
180 file.delete(StudyUtils.class);
182 catch (IOException e) {
187 public static File copyResourceFile(String sourceName, String copyName, Project project, Task task)
189 StudyTaskManager taskManager = StudyTaskManager.getInstance(project);
190 Course course = taskManager.getCourse();
191 int taskNum = task.getIndex() + 1;
192 int lessonNum = task.getLesson().getIndex() + 1;
193 assert course != null;
194 String pathToResource =
195 FileUtil.join(new File(course.getResourcePath()).getParent(), Lesson.LESSON_DIR + lessonNum, Task.TASK_DIR + taskNum);
196 File resourceFile = new File(pathToResource, copyName);
197 FileUtil.copy(new File(pathToResource, sourceName), resourceFile);
202 public static Sdk findPythonSdk(@NotNull final Project project) {
203 return PythonSdkType.findPythonSdk(ModuleManager.getInstance(project).getModules()[0]);
206 public static void markDirAsSourceRoot(@NotNull final VirtualFile dir, @NotNull final Project project) {
207 final Module module = ModuleUtilCore.findModuleForFile(dir, project);
208 if (module == null) {
209 LOG.info("Module for " + dir.getPath() + " was not found");
212 final ModifiableRootModel model = ModuleRootManager.getInstance(module).getModifiableModel();
213 ContentEntry entry = MarkRootActionBase.findContentEntry(model, dir);
215 LOG.info("Content entry for " + dir.getPath() + " was not found");
218 entry.addSourceFolder(dir, false);
219 ApplicationManager.getApplication().runWriteAction(new Runnable() {
223 module.getProject().save();