9c56d0bd432c5555c87cf4b3ef1cc97cf451fd9f
[idea/community.git] / python / educational-core / course-creator / src / com / jetbrains / edu / coursecreator / actions / placeholder / CCChangePlaceholderVisibility.java
1 package com.jetbrains.edu.coursecreator.actions.placeholder;
2
3 import com.intellij.openapi.actionSystem.AnActionEvent;
4 import com.intellij.openapi.actionSystem.Presentation;
5 import com.intellij.openapi.command.undo.BasicUndoableAction;
6 import com.intellij.openapi.command.undo.UnexpectedUndoException;
7 import com.intellij.openapi.editor.Document;
8 import com.intellij.openapi.util.TextRange;
9 import com.intellij.util.DocumentUtil;
10 import com.jetbrains.edu.learning.StudyUtils;
11 import com.jetbrains.edu.learning.core.EduUtils;
12 import com.jetbrains.edu.learning.courseFormat.AnswerPlaceholder;
13 import com.jetbrains.edu.learning.courseFormat.Task;
14 import org.jetbrains.annotations.NotNull;
15 import org.jetbrains.annotations.Nullable;
16
17 import java.util.Collections;
18
19 public abstract class CCChangePlaceholderVisibility extends CCAnswerPlaceholderAction {
20
21   protected CCChangePlaceholderVisibility(@Nullable String text, @Nullable String description) {
22     super(text, description);
23   }
24
25   @Override
26   protected void performAnswerPlaceholderAction(@NotNull CCState state) {
27     AnswerPlaceholder placeholder = state.getAnswerPlaceholder();
28     if (placeholder == null) {
29       return;
30     }
31     EduUtils.runUndoableAction(state.getProject(), getName(), new BasicUndoableAction(state.getEditor().getDocument()) {
32       @Override
33       public void undo() throws UnexpectedUndoException {
34         setVisible(placeholder, isVisible(), state);
35       }
36
37       @Override
38       public void redo() throws UnexpectedUndoException {
39         setVisible(placeholder, !isVisible(), state);
40       }
41     });
42   }
43
44   private void setVisible(AnswerPlaceholder placeholder, boolean visible, CCState state) {
45     placeholder.getActiveSubtaskInfo().setNeedInsertText(visible);
46     int length = isVisible() ? placeholder.getTaskText().length() : 0;
47     placeholder.setLength(length);
48     saveIndent(placeholder, state, !visible);
49     StudyUtils.drawAllAnswerPlaceholders(state.getEditor(), state.getTaskFile());
50   }
51
52   private static void saveIndent(AnswerPlaceholder placeholder, CCState state, boolean visible) {
53     Document document = state.getEditor().getDocument();
54     int offset = placeholder.getOffset();
55     int lineNumber = document.getLineNumber(offset);
56     int nonSpaceCharOffset = DocumentUtil.getFirstNonSpaceCharOffset(document, lineNumber);
57     int newOffset = offset;
58     int endOffset = offset + placeholder.getRealLength();
59     if (!visible && nonSpaceCharOffset == offset) {
60       newOffset = document.getLineStartOffset(lineNumber);
61     }
62     if (visible) {
63       newOffset = DocumentUtil.getFirstNonSpaceCharOffset(document, offset, endOffset);
64     }
65     placeholder.setOffset(newOffset);
66     int delta = offset - newOffset;
67     placeholder.setPossibleAnswer(document.getText(TextRange.create(newOffset, newOffset + delta + placeholder.getRealLength())));
68   }
69
70   protected abstract String getName();
71
72   protected abstract boolean isVisible();
73
74   @Override
75   public void update(AnActionEvent e) {
76     Presentation presentation = e.getPresentation();
77     presentation.setEnabledAndVisible(false);
78     CCState state = getState(e);
79     if (state == null) {
80       return;
81     }
82     AnswerPlaceholder placeholder = state.getAnswerPlaceholder();
83     if (placeholder == null) {
84       return;
85     }
86     Task task = state.getTaskFile().getTask();
87     if (!task.hasSubtasks()) {
88       return;
89     }
90     Integer minSubtaskIndex = Collections.min(placeholder.getSubtaskInfos().keySet());
91     if (placeholder.isActive() && minSubtaskIndex != 0 && minSubtaskIndex == task.getActiveSubtaskIndex() && isAvailable(placeholder)) {
92       presentation.setEnabledAndVisible(true);
93     }
94   }
95
96   protected abstract boolean isAvailable(AnswerPlaceholder placeholder);
97 }