1 package com.jetbrains.edu.learning.actions;
3 import com.intellij.ide.projectView.ProjectView;
4 import com.intellij.openapi.actionSystem.AnActionEvent;
5 import com.intellij.openapi.fileEditor.FileEditorManager;
6 import com.intellij.openapi.project.DumbAwareAction;
7 import com.intellij.openapi.project.Project;
8 import com.intellij.openapi.ui.MessageType;
9 import com.intellij.openapi.ui.popup.Balloon;
10 import com.intellij.openapi.ui.popup.BalloonBuilder;
11 import com.intellij.openapi.ui.popup.JBPopupFactory;
12 import com.intellij.openapi.vfs.VirtualFile;
13 import com.intellij.openapi.wm.ToolWindow;
14 import com.intellij.openapi.wm.ToolWindowId;
15 import com.intellij.openapi.wm.ToolWindowManager;
16 import com.intellij.util.ui.tree.TreeUtil;
17 import com.jetbrains.edu.EduNames;
18 import com.jetbrains.edu.courseFormat.Task;
19 import com.jetbrains.edu.courseFormat.TaskFile;
20 import com.jetbrains.edu.learning.StudyState;
21 import com.jetbrains.edu.learning.StudyUtils;
22 import com.jetbrains.edu.learning.editor.StudyEditor;
23 import org.jetbrains.annotations.NotNull;
24 import org.jetbrains.annotations.Nullable;
27 import javax.swing.tree.TreePath;
31 abstract public class StudyTaskNavigationAction extends DumbAwareAction {
32 public StudyTaskNavigationAction(@Nullable String text, @Nullable String description, @Nullable Icon icon) {
33 super(text, description, icon);
36 public void navigateTask(@NotNull final Project project) {
37 StudyEditor studyEditor = StudyUtils.getSelectedStudyEditor(project);
38 StudyState studyState = new StudyState(studyEditor);
39 if (!studyState.isValid()) {
42 Task nextTask = getTargetTask(studyState.getTask());
43 if (nextTask == null) {
44 BalloonBuilder balloonBuilder =
45 JBPopupFactory.getInstance().createHtmlTextBalloonBuilder(getNavigationFinishedMessage(), MessageType.INFO, null);
46 Balloon balloon = balloonBuilder.createBalloon();
47 assert studyEditor != null;
48 balloon.show(StudyUtils.computeLocation(studyEditor.getEditor()), Balloon.Position.above);
51 for (VirtualFile file : FileEditorManager.getInstance(project).getOpenFiles()) {
52 FileEditorManager.getInstance(project).closeFile(file);
54 int nextTaskIndex = nextTask.getIndex();
55 int lessonIndex = nextTask.getLesson().getIndex();
56 Map<String, TaskFile> nextTaskFiles = nextTask.getTaskFiles();
57 if (nextTaskFiles.isEmpty()) {
60 VirtualFile projectDir = project.getBaseDir();
61 String lessonDirName = EduNames.LESSON + String.valueOf(lessonIndex);
62 if (projectDir == null) {
65 VirtualFile lessonDir = projectDir.findChild(lessonDirName);
66 if (lessonDir == null) {
69 String taskDirName = EduNames.TASK + String.valueOf(nextTaskIndex);
70 VirtualFile taskDir = lessonDir.findChild(taskDirName);
71 if (taskDir == null) {
75 VirtualFile shouldBeActive = getFileToActivate(project, nextTaskFiles, taskDir);
76 JTree tree = ProjectView.getInstance(project).getCurrentProjectViewPane().getTree();
77 TreePath path = TreeUtil.getFirstNodePath(tree);
78 tree.collapsePath(path);
79 if (shouldBeActive != null) {
80 ProjectView.getInstance(project).select(shouldBeActive, shouldBeActive, false);
81 FileEditorManager.getInstance(project).openFile(shouldBeActive, true);
83 ToolWindow runToolWindow = ToolWindowManager.getInstance(project).getToolWindow(ToolWindowId.RUN);
84 if (runToolWindow != null) {
85 runToolWindow.hide(null);
90 protected VirtualFile getFileToActivate(@NotNull Project project, Map<String, TaskFile> nextTaskFiles, VirtualFile taskDir) {
91 VirtualFile shouldBeActive = null;
92 for (Map.Entry<String, TaskFile> entry : nextTaskFiles.entrySet()) {
93 String name = entry.getKey();
94 TaskFile taskFile = entry.getValue();
95 VirtualFile srcDir = taskDir.findChild("src");
96 VirtualFile vf = srcDir == null ? taskDir.findChild(name) : srcDir.findChild(name);
98 FileEditorManager.getInstance(project).openFile(vf, true);
99 if (!taskFile.getAnswerPlaceholders().isEmpty()) {
104 return shouldBeActive != null ? shouldBeActive : getFirstTaskFile(taskDir, project);
108 private static VirtualFile getFirstTaskFile(@NotNull final VirtualFile taskDir, @NotNull final Project project) {
109 for (VirtualFile virtualFile : taskDir.getChildren()) {
110 if (StudyUtils.getTaskFile(project, virtualFile) != null) {
118 public void actionPerformed(AnActionEvent e) {
119 Project project = e.getProject();
120 if (project == null) {
123 navigateTask(project);
126 protected abstract String getNavigationFinishedMessage();
128 protected abstract Task getTargetTask(@NotNull final Task sourceTask);
131 public void update(AnActionEvent e) {
132 StudyUtils.updateAction(e);