1 package com.jetbrains.edu.coursecreator;
3 import com.intellij.openapi.editor.colors.EditorColors;
4 import com.intellij.openapi.editor.colors.EditorColorsManager;
5 import com.intellij.openapi.fileEditor.FileEditor;
6 import com.intellij.openapi.project.DumbAware;
7 import com.intellij.openapi.project.Project;
8 import com.intellij.openapi.ui.popup.JBPopupFactory;
9 import com.intellij.openapi.ui.popup.ListSeparator;
10 import com.intellij.openapi.ui.popup.PopupStep;
11 import com.intellij.openapi.ui.popup.util.BaseListPopupStep;
12 import com.intellij.openapi.util.Key;
13 import com.intellij.openapi.vfs.VirtualFile;
14 import com.intellij.ui.EditorNotificationPanel;
15 import com.intellij.ui.EditorNotifications;
16 import com.intellij.ui.awt.RelativePoint;
17 import com.jetbrains.edu.coursecreator.actions.CCNewSubtaskAction;
18 import com.jetbrains.edu.learning.StudySubtaskUtils;
19 import com.jetbrains.edu.learning.StudyUtils;
20 import com.jetbrains.edu.learning.core.EduNames;
21 import com.jetbrains.edu.learning.courseFormat.Task;
22 import org.jetbrains.annotations.NotNull;
23 import org.jetbrains.annotations.Nullable;
26 import java.util.ArrayList;
27 import java.util.Arrays;
28 import java.util.List;
30 public class CCSubtaskEditorNotificationProvider extends EditorNotifications.Provider<EditorNotificationPanel> implements DumbAware {
31 private static final Key<EditorNotificationPanel> KEY = Key.create("edu.coursecreator.subtask");
32 public static final String SWITCH_SUBTASK = "Switch subtask";
33 public static final Integer ADD_SUBTASK_ID = -1;
34 private final Project myProject;
36 public CCSubtaskEditorNotificationProvider(Project project) {
42 public Key<EditorNotificationPanel> getKey() {
48 public EditorNotificationPanel createNotificationPanel(@NotNull VirtualFile file, @NotNull FileEditor fileEditor) {
49 if (!CCUtils.isCourseCreator(myProject)) {
52 boolean isTestFile = CCUtils.isTestsFile(myProject, file);
53 if (!isTestFile && StudyUtils.getTaskFile(myProject, file) == null) {
56 Task task = StudyUtils.getTaskForFile(myProject, file);
57 if (task == null || !task.hasSubtasks()) {
60 EditorNotificationPanel panel = new EditorNotificationPanel() {
62 public Color getBackground() {
63 Color color = EditorColorsManager.getInstance().getGlobalScheme().getColor(EditorColors.GUTTER_BACKGROUND);
64 return color == null ? super.getBackground() : color;
67 String header = isTestFile ? "test" : "task file";
68 int activeSubtaskIndex = task.getActiveSubtaskIndex() + 1;
69 panel.setText("This is " + header + " for " + EduNames.SUBTASK + " " + activeSubtaskIndex + "/" + task.getSubtaskNum());
70 panel.createActionLabel(SWITCH_SUBTASK, () -> {
71 ArrayList<Integer> values = new ArrayList<>();
72 for (int i = 0; i < task.getSubtaskNum(); i++) {
75 values.add(ADD_SUBTASK_ID);
76 JBPopupFactory.getInstance().createListPopup(new SwitchSubtaskPopupStep(SWITCH_SUBTASK, values, task, file)).show(RelativePoint.getSouthEastOf(panel));
81 private class SwitchSubtaskPopupStep extends BaseListPopupStep<Integer> {
82 private final Task myTask;
83 private final VirtualFile myFile;
85 public SwitchSubtaskPopupStep(@Nullable String title,
87 Task task, VirtualFile file) {
95 public String getTextFor(Integer value) {
96 if (value.equals(ADD_SUBTASK_ID)) {
97 return CCNewSubtaskAction.NEW_SUBTASK;
99 int subtaskNum = value + 1;
100 String text = EduNames.SUBTASK + " " + subtaskNum;
101 if (value == myTask.getActiveSubtaskIndex()) {
102 text += " (selected)";
108 public PopupStep onChosen(Integer selectedValue, boolean finalChoice) {
110 if (selectedValue.equals(ADD_SUBTASK_ID)) {
111 return doFinalStep(() -> CCNewSubtaskAction.addSubtask(myFile, myProject));
113 StudySubtaskUtils.switchStep(myProject, myTask, selectedValue);
115 if (hasSubstep(selectedValue)) {
116 return new ActionsPopupStep(myTask, selectedValue);
119 return super.onChosen(selectedValue, false);
123 public boolean hasSubstep(Integer selectedValue) {
124 return !selectedValue.equals(ADD_SUBTASK_ID);
128 public int getDefaultOptionIndex() {
129 return myTask.getActiveSubtaskIndex() + 1;
134 public ListSeparator getSeparatorAbove(Integer value) {
135 return value.equals(ADD_SUBTASK_ID) ? new ListSeparator() : null;
139 private class ActionsPopupStep extends BaseListPopupStep<String> {
141 public static final String SELECT = "Select";
142 public static final String DELETE = "Delete";
143 private final Task myTask;
144 private final int mySubtaskIndex;
146 public ActionsPopupStep(Task task, int subtaskIndex) {
147 super(null, Arrays.asList(SELECT, DELETE));
149 mySubtaskIndex = subtaskIndex;
153 public PopupStep onChosen(String selectedValue, boolean finalChoice) {
155 if (selectedValue.equals(SELECT)) {
156 StudySubtaskUtils.switchStep(myProject, myTask, mySubtaskIndex);
158 if (mySubtaskIndex != myTask.getSubtaskNum() - 1) {
161 //TODO: delete last subtask
166 return super.onChosen(selectedValue, finalChoice);