select active subtask as default in popup
[idea/community.git] / python / educational-core / course-creator / src / com / jetbrains / edu / coursecreator / CCSubtaskEditorNotificationProvider.java
1 package com.jetbrains.edu.coursecreator;
2
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;
24
25 import java.awt.*;
26 import java.util.ArrayList;
27 import java.util.Arrays;
28 import java.util.List;
29
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;
35
36   public CCSubtaskEditorNotificationProvider(Project project) {
37     myProject = project;
38   }
39
40   @NotNull
41   @Override
42   public Key<EditorNotificationPanel> getKey() {
43     return KEY;
44   }
45
46   @Nullable
47   @Override
48   public EditorNotificationPanel createNotificationPanel(@NotNull VirtualFile file, @NotNull FileEditor fileEditor) {
49     if (!CCUtils.isCourseCreator(myProject)) {
50       return null;
51     }
52     boolean isTestFile = CCUtils.isTestsFile(myProject, file);
53     if (!isTestFile && StudyUtils.getTaskFile(myProject, file) == null) {
54       return null;
55     }
56     Task task = StudyUtils.getTaskForFile(myProject, file);
57     if (task == null || !task.hasSubtasks()) {
58       return null;
59     }
60     EditorNotificationPanel panel = new EditorNotificationPanel() {
61       @Override
62       public Color getBackground() {
63         Color color = EditorColorsManager.getInstance().getGlobalScheme().getColor(EditorColors.GUTTER_BACKGROUND);
64         return color == null ? super.getBackground() : color;
65       }
66     };
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++) {
73         values.add(i);
74       }
75       values.add(ADD_SUBTASK_ID);
76       JBPopupFactory.getInstance().createListPopup(new SwitchSubtaskPopupStep(SWITCH_SUBTASK, values, task, file)).show(RelativePoint.getSouthEastOf(panel));
77     });
78     return panel;
79   }
80
81   private class SwitchSubtaskPopupStep extends BaseListPopupStep<Integer> {
82     private final Task myTask;
83     private final VirtualFile myFile;
84
85     public SwitchSubtaskPopupStep(@Nullable String title,
86                                   List<Integer> values,
87                                   Task task, VirtualFile file) {
88       super(title, values);
89       myTask = task;
90       myFile = file;
91     }
92
93     @NotNull
94     @Override
95     public String getTextFor(Integer value) {
96       if (value.equals(ADD_SUBTASK_ID)) {
97         return CCNewSubtaskAction.NEW_SUBTASK;
98       }
99       int subtaskNum = value + 1;
100       String text = EduNames.SUBTASK + " " + subtaskNum;
101       if (value == myTask.getActiveSubtaskIndex()) {
102         text +=  " (selected)";
103       }
104       return text;
105     }
106
107     @Override
108     public PopupStep onChosen(Integer selectedValue, boolean finalChoice) {
109       if (finalChoice) {
110         if (selectedValue.equals(ADD_SUBTASK_ID)) {
111           return doFinalStep(() -> CCNewSubtaskAction.addSubtask(myFile, myProject));
112         }
113         StudySubtaskUtils.switchStep(myProject, myTask, selectedValue);
114       } else {
115         if (hasSubstep(selectedValue)) {
116           return new ActionsPopupStep(myTask, selectedValue);
117         }
118       }
119       return super.onChosen(selectedValue, false);
120     }
121
122     @Override
123     public boolean hasSubstep(Integer selectedValue) {
124       return !selectedValue.equals(ADD_SUBTASK_ID);
125     }
126
127     @Override
128     public int getDefaultOptionIndex() {
129       return myTask.getActiveSubtaskIndex();
130     }
131
132     @Nullable
133     @Override
134     public ListSeparator getSeparatorAbove(Integer value) {
135       return value.equals(ADD_SUBTASK_ID) ? new ListSeparator() : null;
136     }
137   }
138
139   private class ActionsPopupStep extends BaseListPopupStep<String> {
140
141     public static final String SELECT = "Select";
142     public static final String DELETE = "Delete";
143     private final Task myTask;
144     private final int mySubtaskIndex;
145
146     public ActionsPopupStep(Task task, int subtaskIndex) {
147       super(null, Arrays.asList(SELECT, DELETE));
148       myTask = task;
149       mySubtaskIndex = subtaskIndex;
150     }
151
152     @Override
153     public PopupStep onChosen(String selectedValue, boolean finalChoice) {
154       if (finalChoice) {
155         if (selectedValue.equals(SELECT)) {
156           StudySubtaskUtils.switchStep(myProject, myTask, mySubtaskIndex);
157         } else {
158           if (mySubtaskIndex != myTask.getSubtaskNum() - 1) {
159             //TODO: implement
160           } else {
161             //TODO: delete last subtask
162           }
163           return FINAL_CHOICE;
164         }
165       }
166       return super.onChosen(selectedValue, finalChoice);
167     }
168   }
169 }