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.actionSystem.KeyboardShortcut;
6 import com.intellij.openapi.actionSystem.Presentation;
7 import com.intellij.openapi.application.ApplicationManager;
8 import com.intellij.openapi.command.CommandProcessor;
9 import com.intellij.openapi.diagnostic.Logger;
10 import com.intellij.openapi.editor.Document;
11 import com.intellij.openapi.editor.Editor;
12 import com.intellij.openapi.extensions.Extensions;
13 import com.intellij.openapi.keymap.KeymapUtil;
14 import com.intellij.openapi.project.Project;
15 import com.intellij.openapi.ui.MessageType;
16 import com.intellij.openapi.ui.Messages;
17 import com.intellij.openapi.ui.popup.Balloon;
18 import com.intellij.openapi.ui.popup.BalloonBuilder;
19 import com.intellij.openapi.ui.popup.JBPopupFactory;
20 import com.intellij.openapi.util.Disposer;
21 import com.intellij.openapi.wm.IdeFocusManager;
22 import com.intellij.problems.WolfTheProblemSolver;
23 import com.jetbrains.edu.learning.StudyActionListener;
24 import com.jetbrains.edu.learning.StudyState;
25 import com.jetbrains.edu.learning.StudyTaskManager;
26 import com.jetbrains.edu.learning.StudyUtils;
27 import com.jetbrains.edu.learning.core.EduAnswerPlaceholderPainter;
28 import com.jetbrains.edu.learning.core.EduNames;
29 import com.jetbrains.edu.learning.courseFormat.AnswerPlaceholder;
30 import com.jetbrains.edu.learning.courseFormat.Course;
31 import com.jetbrains.edu.learning.courseFormat.StudyStatus;
32 import com.jetbrains.edu.learning.courseFormat.TaskFile;
33 import com.jetbrains.edu.learning.editor.StudyEditor;
34 import com.jetbrains.edu.learning.navigation.StudyNavigator;
35 import icons.InteractiveLearningIcons;
36 import org.jetbrains.annotations.NotNull;
37 import org.jetbrains.annotations.Nullable;
41 public class StudyRefreshTaskFileAction extends StudyActionWithShortcut {
42 public static final String ACTION_ID = "RefreshTaskAction";
43 public static final String SHORTCUT = "ctrl shift pressed X";
44 private static final Logger LOG = Logger.getInstance(StudyRefreshTaskFileAction.class.getName());
46 public StudyRefreshTaskFileAction() {
47 super("Reset Task File (" + KeymapUtil.getShortcutText(new KeyboardShortcut(KeyStroke.getKeyStroke(SHORTCUT), null)) + ")", "Refresh current task",
48 InteractiveLearningIcons.ResetTaskFile);
51 public static void refresh(@NotNull final Project project) {
52 ApplicationManager.getApplication().invokeLater(() -> ApplicationManager.getApplication().runWriteAction(() -> {
53 StudyEditor studyEditor = StudyUtils.getSelectedStudyEditor(project);
54 StudyState studyState = new StudyState(studyEditor);
55 if (studyEditor == null || !studyState.isValid()) {
56 LOG.info("RefreshTaskFileAction was invoked outside of Study Editor");
59 refreshFile(studyState, project);
63 private static void refreshFile(@NotNull final StudyState studyState, @NotNull final Project project) {
64 final Editor editor = studyState.getEditor();
65 final TaskFile taskFile = studyState.getTaskFile();
66 if (!resetTaskFile(editor.getDocument(), project, taskFile, studyState.getVirtualFile().getName())) {
67 Messages.showInfoMessage("The initial text of task file is unavailable", "Failed to Refresh Task File");
70 WolfTheProblemSolver.getInstance(project).clearProblems(studyState.getVirtualFile());
71 taskFile.setHighlightErrors(false);
72 StudyUtils.drawAllWindows(editor, taskFile);
73 EduAnswerPlaceholderPainter.createGuardedBlocks(editor, taskFile);
74 ApplicationManager.getApplication().invokeLater(
75 () -> IdeFocusManager.getInstance(project).requestFocus(editor.getContentComponent(), true));
77 StudyNavigator.navigateToFirstAnswerPlaceholder(editor, taskFile);
78 showBalloon(project, "You can start again now", MessageType.INFO);
81 private static boolean resetTaskFile(@NotNull final Document document,
82 @NotNull final Project project,
85 if (!resetDocument(document, taskFile, name)) {
88 taskFile.getTask().setStatus(StudyStatus.Unchecked);
89 resetAnswerPlaceholders(taskFile, project);
90 ProjectView.getInstance(project).refresh();
91 StudyUtils.updateToolWindows(project);
95 private static void showBalloon(@NotNull final Project project, String text, @NotNull final MessageType messageType) {
96 BalloonBuilder balloonBuilder =
97 JBPopupFactory.getInstance().createHtmlTextBalloonBuilder(text, messageType, null);
98 final Balloon balloon = balloonBuilder.createBalloon();
99 StudyEditor selectedStudyEditor = StudyUtils.getSelectedStudyEditor(project);
100 assert selectedStudyEditor != null;
101 balloon.show(StudyUtils.computeLocation(selectedStudyEditor.getEditor()), Balloon.Position.above);
102 Disposer.register(project, balloon);
105 private static void resetAnswerPlaceholders(TaskFile selectedTaskFile, Project project) {
106 final StudyTaskManager taskManager = StudyTaskManager.getInstance(project);
107 for (AnswerPlaceholder answerPlaceholder : selectedTaskFile.getAnswerPlaceholders()) {
108 answerPlaceholder.reset();
109 taskManager.setStatus(answerPlaceholder, StudyStatus.Unchecked);
114 private static boolean resetDocument(@NotNull final Document document,
115 @NotNull final TaskFile taskFile,
117 final Document patternDocument = StudyUtils.getPatternDocument(taskFile, fileName);
118 if (patternDocument == null) {
121 StudyUtils.deleteGuardedBlocks(document);
122 taskFile.setTrackChanges(false);
123 clearDocument(document);
124 document.setText(patternDocument.getCharsSequence());
125 taskFile.setTrackChanges(true);
129 private static void clearDocument(@NotNull final Document document) {
130 final int lineCount = document.getLineCount();
131 if (lineCount != 0) {
132 CommandProcessor.getInstance().runUndoTransparentAction(() -> document.deleteString(0, document.getLineEndOffset(lineCount - 1)));
136 public void actionPerformed(@NotNull AnActionEvent event) {
137 final Project project = event.getProject();
138 if (project != null) {
139 for (StudyActionListener listener : Extensions.getExtensions(StudyActionListener.EP_NAME)) {
140 listener.beforeCheck(event);
147 public void update(AnActionEvent event) {
148 StudyUtils.updateAction(event);
149 final Project project = event.getProject();
150 if (project != null) {
151 StudyEditor studyEditor = StudyUtils.getSelectedStudyEditor(project);
152 StudyState studyState = new StudyState(studyEditor);
153 Presentation presentation = event.getPresentation();
154 if (!studyState.isValid()) {
155 presentation.setEnabled(false);
159 Course course = StudyTaskManager.getInstance(project).getCourse();
160 if (course == null) {
163 if (!EduNames.STUDY.equals(course.getCourseMode())) {
164 presentation.setVisible(true);
165 presentation.setEnabled(false);
172 public String getActionId() {
178 public String[] getShortcuts() {
179 return new String[]{SHORTCUT};