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 int subtaskSize = task.getLastSubtaskIndex() + 1;
70 panel.setText("This is " + header + " for " + EduNames.SUBTASK + " " + activeSubtaskIndex + "/" + subtaskSize);
71 panel.createActionLabel(SWITCH_SUBTASK, () -> {
72 ArrayList<Integer> values = new ArrayList<>();
73 for (int i = 0; i <= task.getLastSubtaskIndex(); i++) {
76 values.add(ADD_SUBTASK_ID);
77 JBPopupFactory.getInstance().createListPopup(new SwitchSubtaskPopupStep(SWITCH_SUBTASK, values, task, file)).show(RelativePoint.getSouthEastOf(panel));
82 private class SwitchSubtaskPopupStep extends BaseListPopupStep<Integer> {
83 private final Task myTask;
84 private final VirtualFile myFile;
86 public SwitchSubtaskPopupStep(@Nullable String title,
88 Task task, VirtualFile file) {
96 public String getTextFor(Integer value) {
97 if (value.equals(ADD_SUBTASK_ID)) {
98 return CCNewSubtaskAction.NEW_SUBTASK;
100 int subtaskNum = value + 1;
101 String text = EduNames.SUBTASK + " " + subtaskNum;
102 if (value == myTask.getActiveSubtaskIndex()) {
103 text += " (selected)";
109 public PopupStep onChosen(Integer selectedValue, boolean finalChoice) {
111 if (selectedValue.equals(ADD_SUBTASK_ID)) {
112 return doFinalStep(() -> CCNewSubtaskAction.addSubtask(myFile, myProject));
114 StudySubtaskUtils.switchStep(myProject, myTask, selectedValue);
116 if (hasSubstep(selectedValue)) {
117 return new ActionsPopupStep(myTask, selectedValue);
120 return super.onChosen(selectedValue, false);
124 public boolean hasSubstep(Integer selectedValue) {
125 return !selectedValue.equals(ADD_SUBTASK_ID);
129 public int getDefaultOptionIndex() {
130 return myTask.getActiveSubtaskIndex();
135 public ListSeparator getSeparatorAbove(Integer value) {
136 return value.equals(ADD_SUBTASK_ID) ? new ListSeparator() : null;
140 private class ActionsPopupStep extends BaseListPopupStep<String> {
142 public static final String SELECT = "Select";
143 public static final String DELETE = "Delete";
144 private final Task myTask;
145 private final int mySubtaskIndex;
147 public ActionsPopupStep(Task task, int subtaskIndex) {
148 super(null, Arrays.asList(SELECT, DELETE));
150 mySubtaskIndex = subtaskIndex;
154 public PopupStep onChosen(String selectedValue, boolean finalChoice) {
156 if (selectedValue.equals(SELECT)) {
157 StudySubtaskUtils.switchStep(myProject, myTask, mySubtaskIndex);
159 if (mySubtaskIndex != myTask.getLastSubtaskIndex()) {
162 //TODO: delete last subtask
167 return super.onChosen(selectedValue, finalChoice);