mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
fixes after IDEA-CR-14348 review
This commit is contained in:
committed by
liana.bakradze
parent
6b360083b6
commit
cb304d9c95
+2
-2
@@ -74,10 +74,10 @@ public class CCSubtaskEditorNotificationProvider extends EditorNotifications.Pro
|
||||
return color == null ? super.getBackground() : color;
|
||||
}
|
||||
};
|
||||
String header = isTestFile ? "test" : "task file";
|
||||
String header = (isTestFile ? "test" : "task") + " file";
|
||||
int activeSubtaskIndex = task.getActiveSubtaskIndex() + 1;
|
||||
int subtaskSize = task.getLastSubtaskIndex() + 1;
|
||||
panel.setText("This is " + header + " for " + EduNames.SUBTASK + " " + activeSubtaskIndex + "/" + subtaskSize);
|
||||
panel.setText("This is a " + header + " for " + EduNames.SUBTASK + " " + activeSubtaskIndex + "/" + subtaskSize);
|
||||
panel.createActionLabel(SWITCH_SUBTASK, () -> {
|
||||
ArrayList<Integer> values = new ArrayList<>();
|
||||
for (int i = 0; i <= task.getLastSubtaskIndex(); i++) {
|
||||
|
||||
+26
-17
@@ -13,6 +13,8 @@ import com.intellij.openapi.actionSystem.Presentation;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.project.DumbModePermission;
|
||||
import com.intellij.openapi.project.DumbService;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.ModuleRootModificationUtil;
|
||||
import com.intellij.openapi.roots.ProjectRootManager;
|
||||
@@ -48,7 +50,7 @@ public class CCUtils {
|
||||
public static final String GENERATED_FILES_FOLDER = ".coursecreator";
|
||||
public static final String COURSE_MODE = "Course Creator";
|
||||
|
||||
public static int getSubtaskIndex(Project project, VirtualFile file) {
|
||||
public static int getSubtaskIndex(@NotNull Project project, @NotNull VirtualFile file) {
|
||||
String fileName = file.getName();
|
||||
String name = FileUtil.getNameWithoutExtension(fileName);
|
||||
boolean canBeSubtaskFile = isTestsFile(project, file) || StudyUtils.isTaskDescriptionFile(fileName);
|
||||
@@ -65,7 +67,8 @@ public class CCUtils {
|
||||
}
|
||||
try {
|
||||
return Integer.valueOf(index);
|
||||
} catch (NumberFormatException e) {
|
||||
}
|
||||
catch (NumberFormatException e) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -147,21 +150,27 @@ public class CCUtils {
|
||||
return folder;
|
||||
}
|
||||
final Ref<VirtualFile> generatedRoot = new Ref<>();
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
DumbService.allowStartingDumbModeInside(DumbModePermission.MAY_START_BACKGROUND, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
generatedRoot.set(baseDir.createChildDirectory(this, GENERATED_FILES_FOLDER));
|
||||
VirtualFile contentRootForFile =
|
||||
ProjectRootManager.getInstance(module.getProject()).getFileIndex().getContentRootForFile(generatedRoot.get());
|
||||
if (contentRootForFile == null) {
|
||||
return;
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
generatedRoot.set(baseDir.createChildDirectory(this, GENERATED_FILES_FOLDER));
|
||||
VirtualFile contentRootForFile =
|
||||
ProjectRootManager.getInstance(module.getProject()).getFileIndex().getContentRootForFile(generatedRoot.get());
|
||||
if (contentRootForFile == null) {
|
||||
return;
|
||||
}
|
||||
ModuleRootModificationUtil.updateExcludedFolders(module, contentRootForFile, Collections.emptyList(),
|
||||
Collections.singletonList(generatedRoot.get().getUrl()));
|
||||
}
|
||||
catch (IOException e) {
|
||||
LOG.info("Failed to create folder for generated files", e);
|
||||
}
|
||||
}
|
||||
ModuleRootModificationUtil.updateExcludedFolders(module, contentRootForFile, Collections.emptyList(), Collections.singletonList(generatedRoot.get().getUrl()));
|
||||
}
|
||||
catch (IOException e) {
|
||||
LOG.info("Failed to create folder for generated files", e);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
return generatedRoot.get();
|
||||
@@ -292,9 +301,9 @@ public class CCUtils {
|
||||
}
|
||||
|
||||
public static void createTaskContent(@NotNull Project project,
|
||||
@Nullable IdeView view,
|
||||
@NotNull Course course,
|
||||
PsiDirectory taskDirectory) {
|
||||
@Nullable IdeView view,
|
||||
@NotNull Course course,
|
||||
PsiDirectory taskDirectory) {
|
||||
CCLanguageManager manager = getStudyLanguageManager(course);
|
||||
if (manager == null) {
|
||||
return;
|
||||
|
||||
+7
-5
@@ -1,9 +1,11 @@
|
||||
package com.jetbrains.edu.coursecreator.actions.placeholder;
|
||||
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.jetbrains.edu.learning.StudyUtils;
|
||||
import com.jetbrains.edu.learning.courseFormat.AnswerPlaceholder;
|
||||
import com.jetbrains.edu.learning.courseFormat.AnswerPlaceholderSubtaskInfo;
|
||||
import com.jetbrains.edu.learning.courseFormat.TaskFile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class CCActivatePlaceholder extends CCSubtaskPlaceholderAction {
|
||||
|
||||
@@ -14,9 +16,9 @@ public class CCActivatePlaceholder extends CCSubtaskPlaceholderAction {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AnswerPlaceholderSubtaskInfo getInfo(CCState state,
|
||||
protected AnswerPlaceholderSubtaskInfo getInfo(@NotNull CCState state,
|
||||
int subtaskIndex,
|
||||
AnswerPlaceholder existingPlaceholder) {
|
||||
@NotNull AnswerPlaceholder existingPlaceholder) {
|
||||
int visibleLength = existingPlaceholder.getVisibleLength(subtaskIndex);
|
||||
int placeholderOffset = existingPlaceholder.getOffset();
|
||||
String possibleAnswer = state.getEditor().getDocument().getText(TextRange.create(placeholderOffset, placeholderOffset + visibleLength));
|
||||
@@ -31,18 +33,18 @@ public class CCActivatePlaceholder extends CCSubtaskPlaceholderAction {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void redoAction(AnswerPlaceholder existingPlaceholder, int subtaskIndex, AnswerPlaceholderSubtaskInfo info) {
|
||||
protected void redoAction(@NotNull AnswerPlaceholder existingPlaceholder, int subtaskIndex, @NotNull AnswerPlaceholderSubtaskInfo info) {
|
||||
existingPlaceholder.getSubtaskInfos().put(subtaskIndex, info);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void undoAction(AnswerPlaceholder existingPlaceholder, int subtaskIndex, AnswerPlaceholderSubtaskInfo info) {
|
||||
protected void undoAction(@NotNull AnswerPlaceholder existingPlaceholder, int subtaskIndex, @NotNull AnswerPlaceholderSubtaskInfo info) {
|
||||
existingPlaceholder.getSubtaskInfos().remove(subtaskIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isAvailable(TaskFile taskFile, int offset) {
|
||||
AnswerPlaceholder existingPlaceholder = taskFile.getAnswerPlaceholder(offset, taskFile.getAnswerPlaceholders());
|
||||
AnswerPlaceholder existingPlaceholder = StudyUtils.getAnswerPlaceholder(offset, taskFile.getAnswerPlaceholders());
|
||||
return existingPlaceholder != null && !existingPlaceholder.isActive();
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -145,7 +145,7 @@ public class CCAddAnswerPlaceholder extends CCAnswerPlaceholderAction {
|
||||
return !arePlaceholdersIntersect(taskFile, start, end);
|
||||
}
|
||||
int offset = editor.getCaretModel().getOffset();
|
||||
return taskFile.getAnswerPlaceholder(offset, taskFile.getAnswerPlaceholders()) == null;
|
||||
return StudyUtils.getAnswerPlaceholder(offset, taskFile.getAnswerPlaceholders()) == null;
|
||||
}
|
||||
|
||||
protected CCCreateAnswerPlaceholderDialog createDialog(Project project, AnswerPlaceholder answerPlaceholder) {
|
||||
|
||||
+5
-4
@@ -3,6 +3,7 @@ package com.jetbrains.edu.coursecreator.actions.placeholder;
|
||||
import com.jetbrains.edu.learning.courseFormat.AnswerPlaceholder;
|
||||
import com.jetbrains.edu.learning.courseFormat.AnswerPlaceholderSubtaskInfo;
|
||||
import com.jetbrains.edu.learning.courseFormat.TaskFile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
@@ -14,14 +15,14 @@ public class CCDeactivatePlaceholder extends CCSubtaskPlaceholderAction {
|
||||
super(TITLE, TITLE);
|
||||
}
|
||||
|
||||
protected void undoAction(AnswerPlaceholder existingPlaceholder, int subtaskIndex, AnswerPlaceholderSubtaskInfo info) {
|
||||
protected void undoAction(@NotNull AnswerPlaceholder existingPlaceholder, int subtaskIndex, @NotNull AnswerPlaceholderSubtaskInfo info) {
|
||||
existingPlaceholder.getSubtaskInfos().put(subtaskIndex, info);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AnswerPlaceholderSubtaskInfo getInfo(CCState state,
|
||||
protected AnswerPlaceholderSubtaskInfo getInfo(@NotNull CCState state,
|
||||
int subtaskIndex,
|
||||
AnswerPlaceholder existingPlaceholder) {
|
||||
@NotNull AnswerPlaceholder existingPlaceholder) {
|
||||
return existingPlaceholder.getSubtaskInfos().get(subtaskIndex);
|
||||
}
|
||||
|
||||
@@ -30,7 +31,7 @@ public class CCDeactivatePlaceholder extends CCSubtaskPlaceholderAction {
|
||||
return TITLE;
|
||||
}
|
||||
|
||||
protected void redoAction(AnswerPlaceholder existingPlaceholder, int subtaskIndex, AnswerPlaceholderSubtaskInfo info) {
|
||||
protected void redoAction(@NotNull AnswerPlaceholder existingPlaceholder, int subtaskIndex, @NotNull AnswerPlaceholderSubtaskInfo info) {
|
||||
existingPlaceholder.getSubtaskInfos().remove(subtaskIndex);
|
||||
}
|
||||
|
||||
|
||||
+11
-13
@@ -23,21 +23,20 @@ public class CCDeleteAnswerPlaceholder extends CCAnswerPlaceholderAction {
|
||||
Project project = state.getProject();
|
||||
TaskFile taskFile = state.getTaskFile();
|
||||
AnswerPlaceholder answerPlaceholder = state.getAnswerPlaceholder();
|
||||
EduUtils.runUndoableAction(project, "Delete Answer Placeholder", new CCAddAnswerPlaceholder.AddAction(answerPlaceholder, taskFile, state.getEditor()) {
|
||||
@Override
|
||||
public void undo() throws UnexpectedUndoException {
|
||||
super.redo();
|
||||
}
|
||||
EduUtils.runUndoableAction(project, "Delete Answer Placeholder",
|
||||
new CCAddAnswerPlaceholder.AddAction(answerPlaceholder, taskFile, state.getEditor()) {
|
||||
@Override
|
||||
public void undo() throws UnexpectedUndoException {
|
||||
super.redo();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void redo() throws UnexpectedUndoException {
|
||||
super.undo();
|
||||
}
|
||||
});
|
||||
@Override
|
||||
public void redo() throws UnexpectedUndoException {
|
||||
super.undo();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
private static boolean canDeletePlaceholder(@NotNull CCState state) {
|
||||
if (state.getEditor().getSelectionModel().hasSelection()) {
|
||||
return false;
|
||||
@@ -59,5 +58,4 @@ public class CCDeleteAnswerPlaceholder extends CCAnswerPlaceholderAction {
|
||||
presentation.setEnabledAndVisible(true);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+4
-4
@@ -24,7 +24,7 @@ public abstract class CCSubtaskPlaceholderAction extends CCAnswerPlaceholderActi
|
||||
final int offset = editor.getCaretModel().getOffset();
|
||||
TaskFile taskFile = state.getTaskFile();
|
||||
int subtaskIndex = state.getTaskFile().getTask().getActiveSubtaskIndex();
|
||||
AnswerPlaceholder existingPlaceholder = taskFile.getAnswerPlaceholder(offset, taskFile.getAnswerPlaceholders());
|
||||
AnswerPlaceholder existingPlaceholder = StudyUtils.getAnswerPlaceholder(offset, taskFile.getAnswerPlaceholders());
|
||||
if (existingPlaceholder == null) {
|
||||
return;
|
||||
}
|
||||
@@ -47,13 +47,13 @@ public abstract class CCSubtaskPlaceholderAction extends CCAnswerPlaceholderActi
|
||||
});
|
||||
}
|
||||
|
||||
protected abstract AnswerPlaceholderSubtaskInfo getInfo(CCState state, int subtaskIndex, AnswerPlaceholder existingPlaceholder);
|
||||
protected abstract AnswerPlaceholderSubtaskInfo getInfo(@NotNull CCState state, int subtaskIndex, @NotNull AnswerPlaceholder existingPlaceholder);
|
||||
|
||||
protected abstract String getTitle();
|
||||
|
||||
protected abstract void redoAction(AnswerPlaceholder existingPlaceholder, int subtaskIndex, AnswerPlaceholderSubtaskInfo info);
|
||||
protected abstract void redoAction(@NotNull AnswerPlaceholder existingPlaceholder, int subtaskIndex, @NotNull AnswerPlaceholderSubtaskInfo info);
|
||||
|
||||
protected abstract void undoAction(AnswerPlaceholder existingPlaceholder, int subtaskIndex, AnswerPlaceholderSubtaskInfo info);
|
||||
protected abstract void undoAction(@NotNull AnswerPlaceholder existingPlaceholder, int subtaskIndex, @NotNull AnswerPlaceholderSubtaskInfo info);
|
||||
|
||||
@Override
|
||||
public void update(AnActionEvent e) {
|
||||
|
||||
+1
-2
@@ -219,8 +219,7 @@ public class StudySerializationUtils {
|
||||
for (Element placeholder : getChildList(taskFileElement, ANSWER_PLACEHOLDERS)) {
|
||||
Element valueElement = new Element(SUBTASK_INFO);
|
||||
addChildMap(placeholder, SUBTASK_INFOS, Collections.singletonMap(String.valueOf(0), valueElement));
|
||||
for (String childName : ContainerUtil
|
||||
.list(HINT, ADDITIONAL_HINTS, POSSIBLE_ANSWER, SELECTED, STATUS, TASK_TEXT)) {
|
||||
for (String childName : ContainerUtil.list(HINT, ADDITIONAL_HINTS, POSSIBLE_ANSWER, SELECTED, STATUS, TASK_TEXT)) {
|
||||
Element child = getChildWithName(placeholder, childName);
|
||||
valueElement.addContent(child.clone());
|
||||
}
|
||||
|
||||
@@ -798,4 +798,15 @@ public class StudyUtils {
|
||||
toolWindowManager.registerToolWindow(StudyToolWindowFactory.STUDY_TOOL_WINDOW, true, ToolWindowAnchor.RIGHT, project, true);
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable public static AnswerPlaceholder getAnswerPlaceholder(int offset, List<AnswerPlaceholder> placeholders) {
|
||||
for (AnswerPlaceholder placeholder : placeholders) {
|
||||
int placeholderStart = placeholder.getOffset();
|
||||
int placeholderEnd = placeholderStart + placeholder.getRealLength();
|
||||
if (placeholderStart <= offset && offset <= placeholderEnd) {
|
||||
return placeholder;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
+1
-2
@@ -193,8 +193,7 @@ public class StudyCheckTask extends com.intellij.openapi.progress.Task.Backgroun
|
||||
int visibleSubtaskIndex = myTask.getActiveSubtaskIndex() + 1;
|
||||
ApplicationManager.getApplication().invokeLater(() -> {
|
||||
int subtaskSize = myTask.getLastSubtaskIndex() + 1;
|
||||
String resultMessage = !hasMoreSubtasks ? message : "Subtask " + visibleSubtaskIndex + "/" +
|
||||
subtaskSize + " solved";
|
||||
String resultMessage = !hasMoreSubtasks ? message : "Subtask " + visibleSubtaskIndex + "/" + subtaskSize + " solved";
|
||||
StudyCheckUtils.showTestResultPopUp(resultMessage, MessageType.INFO.getPopupBackground(), myProject);
|
||||
if (hasMoreSubtasks) {
|
||||
int nextSubtaskIndex = myTask.getActiveSubtaskIndex() + 1;
|
||||
|
||||
+18
-17
@@ -114,16 +114,19 @@ public class StudyCheckUtils {
|
||||
|
||||
public static void runSmartTestProcess(@NotNull final VirtualFile taskDir,
|
||||
@NotNull final StudyTestRunner testRunner,
|
||||
final String taskFileName,
|
||||
@NotNull final String taskFileName,
|
||||
@NotNull final TaskFile taskFile,
|
||||
@NotNull final Project project) {
|
||||
final TaskFile answerTaskFile = new TaskFile();
|
||||
answerTaskFile.name = taskFileName;
|
||||
final VirtualFile virtualFile = taskDir.findChild(taskFileName);
|
||||
if (virtualFile == null) {
|
||||
return;
|
||||
}
|
||||
final VirtualFile answerFile = getCopyWithAnswers(taskDir, virtualFile, taskFile, answerTaskFile);
|
||||
Pair<VirtualFile, TaskFile> pair = getCopyWithAnswers(taskDir, virtualFile, taskFile);
|
||||
if (pair == null) {
|
||||
return;
|
||||
}
|
||||
VirtualFile answerFile = pair.getFirst();
|
||||
TaskFile answerTaskFile = pair.getSecond();
|
||||
for (final AnswerPlaceholder answerPlaceholder : answerTaskFile.getActivePlaceholders()) {
|
||||
final Document document = FileDocumentManager.getInstance().getDocument(virtualFile);
|
||||
if (document == null) {
|
||||
@@ -136,36 +139,34 @@ public class StudyCheckUtils {
|
||||
}
|
||||
|
||||
|
||||
private static VirtualFile getCopyWithAnswers(@NotNull final VirtualFile taskDir,
|
||||
private static Pair<VirtualFile, TaskFile> getCopyWithAnswers(@NotNull final VirtualFile taskDir,
|
||||
@NotNull final VirtualFile file,
|
||||
@NotNull final TaskFile source,
|
||||
@NotNull TaskFile target) {
|
||||
VirtualFile copy = null;
|
||||
@NotNull final TaskFile source) {
|
||||
try {
|
||||
|
||||
copy = file.copy(taskDir, taskDir, file.getNameWithoutExtension() + EduNames.ANSWERS_POSTFIX + "." + file.getExtension());
|
||||
VirtualFile answerFile = file.copy(taskDir, taskDir, file.getNameWithoutExtension() + EduNames.ANSWERS_POSTFIX + "." + file.getExtension());
|
||||
final FileDocumentManager documentManager = FileDocumentManager.getInstance();
|
||||
final Document document = documentManager.getDocument(copy);
|
||||
final Document document = documentManager.getDocument(answerFile);
|
||||
if (document != null) {
|
||||
target = source.getTask().copy().getTaskFile(file.getName());
|
||||
if (target == null) {
|
||||
return copy;
|
||||
TaskFile answerTaskFile = source.getTask().copy().getTaskFile(file.getName());
|
||||
if (answerTaskFile == null) {
|
||||
return null;
|
||||
}
|
||||
EduDocumentListener listener = new EduDocumentListener(target);
|
||||
EduDocumentListener listener = new EduDocumentListener(answerTaskFile);
|
||||
document.addDocumentListener(listener);
|
||||
for (AnswerPlaceholder answerPlaceholder : target.getActivePlaceholders()) {
|
||||
for (AnswerPlaceholder answerPlaceholder : answerTaskFile.getActivePlaceholders()) {
|
||||
final int start = answerPlaceholder.getOffset();
|
||||
final int end = start + answerPlaceholder.getRealLength();
|
||||
final String text = answerPlaceholder.getPossibleAnswer();
|
||||
document.replaceString(start, end, text);
|
||||
}
|
||||
ApplicationManager.getApplication().runWriteAction(() -> documentManager.saveDocument(document));
|
||||
return Pair.create(answerFile, answerTaskFile);
|
||||
}
|
||||
}
|
||||
catch (IOException e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
return copy;
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
+4
-2
@@ -50,8 +50,10 @@ public class StudySmartChecker {
|
||||
if (windowDocument != null) {
|
||||
final File resourceFile =
|
||||
StudyUtils.copyResourceFile(virtualFile.getName(), windowCopy.getName(), project, usersTaskFile.getTask());
|
||||
final TaskFile windowTaskFile = new TaskFile();
|
||||
TaskFile.copy(answerTaskFile, windowTaskFile);
|
||||
TaskFile windowTaskFile = answerTaskFile.getTask().copy().getTaskFile(virtualFile.getName());
|
||||
if (windowTaskFile == null) {
|
||||
return;
|
||||
}
|
||||
EduDocumentListener listener = new EduDocumentListener(windowTaskFile);
|
||||
windowDocument.addDocumentListener(listener);
|
||||
int start = placeholder.getOffset();
|
||||
|
||||
+7
-6
@@ -16,6 +16,7 @@ import com.jetbrains.edu.learning.courseFormat.AnswerPlaceholder;
|
||||
import com.jetbrains.edu.learning.courseFormat.AnswerPlaceholderSubtaskInfo;
|
||||
import com.jetbrains.edu.learning.courseFormat.TaskFile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.awt.*;
|
||||
import java.util.List;
|
||||
@@ -37,7 +38,8 @@ public class EduAnswerPlaceholderPainter {
|
||||
textAttributes.setEffectColor(color);
|
||||
if (placeholder.isActive()) {
|
||||
drawAnswerPlaceholder(editor, placeholder, textAttributes, PLACEHOLDERS_LAYER);
|
||||
} else if (!placeholder.getUseLength()) {
|
||||
}
|
||||
else if (!placeholder.getUseLength()) {
|
||||
int offset = placeholder.getOffset();
|
||||
drawAnswerPlaceholderFromPrevStep(editor, offset, offset + placeholder.getVisibleLength(placeholder.getActiveSubtaskIndex()));
|
||||
}
|
||||
@@ -45,7 +47,7 @@ public class EduAnswerPlaceholderPainter {
|
||||
|
||||
public static void drawAnswerPlaceholder(@NotNull Editor editor,
|
||||
@NotNull AnswerPlaceholder placeholder,
|
||||
TextAttributes textAttributes,
|
||||
@Nullable TextAttributes textAttributes,
|
||||
int placeholdersLayer) {
|
||||
int startOffset = placeholder.getOffset();
|
||||
if (startOffset == -1) {
|
||||
@@ -69,16 +71,15 @@ public class EduAnswerPlaceholderPainter {
|
||||
public static void drawAnswerPlaceholder(@NotNull Editor editor,
|
||||
int start,
|
||||
int end,
|
||||
TextAttributes textAttributes,
|
||||
@Nullable TextAttributes textAttributes,
|
||||
int placeholdersLayer) {
|
||||
final Project project = editor.getProject();
|
||||
assert project != null;
|
||||
if (start == -1) {
|
||||
return;
|
||||
}
|
||||
RangeHighlighter
|
||||
highlighter = editor.getMarkupModel().addRangeHighlighter(start, end, placeholdersLayer,
|
||||
textAttributes, HighlighterTargetArea.EXACT_RANGE);
|
||||
RangeHighlighter highlighter = editor.getMarkupModel().addRangeHighlighter(start, end, placeholdersLayer,
|
||||
textAttributes, HighlighterTargetArea.EXACT_RANGE);
|
||||
highlighter.setGreedyToLeft(true);
|
||||
highlighter.setGreedyToRight(true);
|
||||
}
|
||||
|
||||
+8
-7
@@ -24,7 +24,8 @@ public class AnswerPlaceholder {
|
||||
@SerializedName("offset")
|
||||
@Expose private int myOffset = -1;
|
||||
|
||||
@Expose private int length = -1;
|
||||
@SerializedName("length")
|
||||
@Expose private int myLength = -1;
|
||||
|
||||
private int myIndex = -1;
|
||||
private MyInitialState myInitialState;
|
||||
@@ -41,7 +42,7 @@ public class AnswerPlaceholder {
|
||||
public void initAnswerPlaceholder(final TaskFile file, boolean isRestarted) {
|
||||
setTaskFile(file);
|
||||
if (!isRestarted) {
|
||||
setInitialState(new MyInitialState(myOffset, length));
|
||||
setInitialState(new MyInitialState(myOffset, myLength));
|
||||
for (AnswerPlaceholderSubtaskInfo info : getSubtaskInfos().values()) {
|
||||
info.setStatus(file.getTask().getStatus());
|
||||
}
|
||||
@@ -60,11 +61,11 @@ public class AnswerPlaceholder {
|
||||
* in actions {@link AnswerPlaceholder#getRealLength()} should be used
|
||||
*/
|
||||
public int getLength() {
|
||||
return length;
|
||||
return myLength;
|
||||
}
|
||||
|
||||
public void setLength(int length) {
|
||||
this.length = length;
|
||||
myLength = length;
|
||||
}
|
||||
|
||||
@Transient
|
||||
@@ -114,7 +115,7 @@ public class AnswerPlaceholder {
|
||||
*/
|
||||
public void reset() {
|
||||
myOffset = myInitialState.getOffset();
|
||||
length = myInitialState.getLength();
|
||||
myLength = myInitialState.getLength();
|
||||
}
|
||||
|
||||
@Transient
|
||||
@@ -237,13 +238,13 @@ public class AnswerPlaceholder {
|
||||
int minIndex = Collections.min(mySubtaskInfos.keySet());
|
||||
AnswerPlaceholderSubtaskInfo minInfo = mySubtaskInfos.get(minIndex);
|
||||
if (minIndex == subtaskIndex) {
|
||||
return getUseLength() ? length : minInfo.getPossibleAnswer().length();
|
||||
return getUseLength() ? myLength : minInfo.getPossibleAnswer().length();
|
||||
}
|
||||
if (minIndex > subtaskIndex) {
|
||||
return minInfo.isNeedInsertText() ? 0 : minInfo.getPlaceholderText().length();
|
||||
}
|
||||
int maxIndex = Collections.max(ContainerUtil.filter(mySubtaskInfos.keySet(), i -> i <= subtaskIndex));
|
||||
return getUseLength() ? length : mySubtaskInfos.get(maxIndex).getPossibleAnswer().length();
|
||||
return getUseLength() ? myLength : mySubtaskInfos.get(maxIndex).getPossibleAnswer().length();
|
||||
}
|
||||
|
||||
public void switchSubtask(@NotNull Project project, @NotNull Document document, int fromSubtask, int toSubtask) {
|
||||
|
||||
+3
-3
@@ -15,7 +15,7 @@ public class AnswerPlaceholderSubtaskInfo {
|
||||
@Expose private List<String> myHints = new ArrayList<>();
|
||||
|
||||
@SerializedName("possible_answer")
|
||||
@Expose private String possibleAnswer = "";
|
||||
@Expose private String myPossibleAnswer = "";
|
||||
|
||||
@SerializedName("placeholder_text")
|
||||
@Expose private String myPlaceholderText;
|
||||
@@ -60,11 +60,11 @@ public class AnswerPlaceholderSubtaskInfo {
|
||||
}
|
||||
|
||||
public String getPossibleAnswer() {
|
||||
return possibleAnswer;
|
||||
return myPossibleAnswer;
|
||||
}
|
||||
|
||||
public void setPossibleAnswer(String possibleAnswer) {
|
||||
this.possibleAnswer = possibleAnswer;
|
||||
myPossibleAnswer = possibleAnswer;
|
||||
}
|
||||
|
||||
public String getPlaceholderText() {
|
||||
|
||||
+2
-12
@@ -3,6 +3,7 @@ package com.jetbrains.edu.learning.courseFormat;
|
||||
import com.google.gson.annotations.Expose;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import com.intellij.util.xmlb.annotations.Transient;
|
||||
import com.jetbrains.edu.learning.StudyUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -87,18 +88,7 @@ public class TaskFile {
|
||||
*/
|
||||
@Nullable
|
||||
public AnswerPlaceholder getAnswerPlaceholder(int offset) {
|
||||
return getAnswerPlaceholder(offset, getActivePlaceholders());
|
||||
}
|
||||
|
||||
@Nullable public AnswerPlaceholder getAnswerPlaceholder(int offset, List<AnswerPlaceholder> placeholders) {
|
||||
for (AnswerPlaceholder placeholder : placeholders) {
|
||||
int placeholderStart = placeholder.getOffset();
|
||||
int placeholderEnd = placeholderStart + placeholder.getRealLength();
|
||||
if (placeholderStart <= offset && offset <= placeholderEnd) {
|
||||
return placeholder;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
return StudyUtils.getAnswerPlaceholder(offset, getActivePlaceholders());
|
||||
}
|
||||
|
||||
public boolean isTrackLengths() {
|
||||
|
||||
+36
-36
@@ -109,22 +109,22 @@ public class StudyNavigator {
|
||||
|
||||
@Nullable
|
||||
public static VirtualFile getFileToActivate(@NotNull Project project, Map<String, TaskFile> nextTaskFiles, VirtualFile taskDir) {
|
||||
VirtualFile shouldBeActive = null;
|
||||
VirtualFile fileToActivate = null;
|
||||
for (Map.Entry<String, TaskFile> entry : nextTaskFiles.entrySet()) {
|
||||
String name = entry.getKey();
|
||||
TaskFile taskFile = entry.getValue();
|
||||
VirtualFile srcDir = taskDir.findChild(EduNames.SRC);
|
||||
VirtualFile vf = srcDir == null ? taskDir.findChild(name) : srcDir.findChild(name);
|
||||
if (vf != null) {
|
||||
if (shouldBeActive != null) {
|
||||
if (fileToActivate != null) {
|
||||
FileEditorManager.getInstance(project).openFile(vf, true);
|
||||
}
|
||||
if (shouldBeActive == null && !taskFile.getActivePlaceholders().isEmpty()) {
|
||||
shouldBeActive = vf;
|
||||
if (fileToActivate == null && !taskFile.getActivePlaceholders().isEmpty()) {
|
||||
fileToActivate = vf;
|
||||
}
|
||||
}
|
||||
}
|
||||
return shouldBeActive != null ? shouldBeActive : getFirstTaskFile(taskDir, project);
|
||||
return fileToActivate != null ? fileToActivate : getFirstTaskFile(taskDir, project);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -178,9 +178,10 @@ public class StudyNavigator {
|
||||
FileEditorManager.getInstance(project).openFile(virtualFile, true);
|
||||
}
|
||||
EduUsagesCollector.taskNavigation();
|
||||
VirtualFile shouldBeActive = getFileToActivate(project, nextTaskFiles, taskDir);
|
||||
|
||||
updateProjectView(project, shouldBeActive);
|
||||
VirtualFile fileToActivate = getFileToActivate(project, nextTaskFiles, taskDir);
|
||||
if (fileToActivate != null) {
|
||||
updateProjectView(project, fileToActivate);
|
||||
}
|
||||
|
||||
StudyUtils.selectFirstAnswerPlaceholder(StudyUtils.getSelectedStudyEditor(project), project);
|
||||
ToolWindow runToolWindow = ToolWindowManager.getInstance(project).getToolWindow(ToolWindowId.RUN);
|
||||
@@ -189,38 +190,37 @@ public class StudyNavigator {
|
||||
}
|
||||
}
|
||||
|
||||
private static void updateProjectView(@NotNull Project project, VirtualFile shouldBeActive) {
|
||||
private static void updateProjectView(@NotNull Project project, @NotNull VirtualFile fileToActivate) {
|
||||
JTree tree = ProjectView.getInstance(project).getCurrentProjectViewPane().getTree();
|
||||
if (shouldBeActive != null) {
|
||||
ProjectView.getInstance(project).selectCB(shouldBeActive, shouldBeActive, false).doWhenDone(() -> {
|
||||
List<TreePath> paths = TreeUtil.collectExpandedPaths(tree);
|
||||
List<TreePath> toCollapse = new ArrayList<>();
|
||||
TreePath selectedPath = tree.getSelectionPath();
|
||||
for (TreePath treePath : paths) {
|
||||
if (treePath.isDescendant(selectedPath)) {
|
||||
continue;
|
||||
ProjectView.getInstance(project).selectCB(fileToActivate, fileToActivate, false).doWhenDone(() -> {
|
||||
List<TreePath> paths = TreeUtil.collectExpandedPaths(tree);
|
||||
List<TreePath> toCollapse = new ArrayList<>();
|
||||
TreePath selectedPath = tree.getSelectionPath();
|
||||
for (TreePath treePath : paths) {
|
||||
if (treePath.isDescendant(selectedPath)) {
|
||||
continue;
|
||||
}
|
||||
if (toCollapse.isEmpty()) {
|
||||
toCollapse.add(treePath);
|
||||
continue;
|
||||
}
|
||||
for (int i = 0; i < toCollapse.size(); i++) {
|
||||
TreePath path = toCollapse.get(i);
|
||||
if (treePath.isDescendant(path)) {
|
||||
toCollapse.set(i, treePath);
|
||||
}
|
||||
if (toCollapse.isEmpty()) {
|
||||
toCollapse.add(treePath);
|
||||
continue;
|
||||
}
|
||||
for (int i = 0; i < toCollapse.size(); i++) {
|
||||
TreePath path = toCollapse.get(i);
|
||||
if (treePath.isDescendant(path)) {
|
||||
toCollapse.set(i, treePath);
|
||||
} else {
|
||||
if (!path.isDescendant(treePath)) {
|
||||
toCollapse.add(treePath);
|
||||
}
|
||||
else {
|
||||
if (!path.isDescendant(treePath)) {
|
||||
toCollapse.add(treePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (TreePath path : toCollapse) {
|
||||
tree.collapsePath(path);
|
||||
tree.fireTreeCollapsed(path);
|
||||
}
|
||||
});
|
||||
FileEditorManager.getInstance(project).openFile(shouldBeActive, true);
|
||||
}
|
||||
}
|
||||
for (TreePath path : toCollapse) {
|
||||
tree.collapsePath(path);
|
||||
tree.fireTreeCollapsed(path);
|
||||
}
|
||||
});
|
||||
FileEditorManager.getInstance(project).openFile(fileToActivate, true);
|
||||
}
|
||||
}
|
||||
|
||||
-1
@@ -41,7 +41,6 @@ public class LessonDirectoryNode extends StudyDirectoryNode {
|
||||
JBColor color = isSolved ? JBColor.BLACK : LIGHT_GREEN;
|
||||
Icon icon = isSolved ? InteractiveLearningIcons.Lesson : InteractiveLearningIcons.LessonCompl;
|
||||
updatePresentation(data, myLesson.getName(), color, icon, null);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+16
-9
@@ -119,13 +119,14 @@ public class EduStepicConnector {
|
||||
final URI url;
|
||||
try {
|
||||
url = new URIBuilder(EduStepicNames.COURSES).addParameter("is_idea_compatible", "true").
|
||||
addParameter("page", String.valueOf(pageNumber)).build();
|
||||
addParameter("page", String.valueOf(pageNumber)).build();
|
||||
}
|
||||
catch (URISyntaxException e) {
|
||||
LOG.error(e.getMessage());
|
||||
return false;
|
||||
}
|
||||
final StepicWrappers.CoursesContainer coursesContainer = EduStepicClient.getFromStepic(url.toString(), StepicWrappers.CoursesContainer.class);
|
||||
final StepicWrappers.CoursesContainer coursesContainer =
|
||||
EduStepicClient.getFromStepic(url.toString(), StepicWrappers.CoursesContainer.class);
|
||||
addAvailableCourses(result, coursesContainer);
|
||||
return coursesContainer.meta.containsKey("has_next") && coursesContainer.meta.get("has_next") == Boolean.TRUE;
|
||||
}
|
||||
@@ -167,7 +168,8 @@ public class EduStepicConnector {
|
||||
try {
|
||||
Integer version = Integer.valueOf(versionString);
|
||||
return version <= CURRENT_VERSION;
|
||||
} catch (NumberFormatException e) {
|
||||
}
|
||||
catch (NumberFormatException e) {
|
||||
LOG.info("Wrong version format", e);
|
||||
return false;
|
||||
}
|
||||
@@ -180,7 +182,7 @@ public class EduStepicConnector {
|
||||
course.setAdaptive(info.isAdaptive());
|
||||
course.setId(info.getId());
|
||||
course.setUpdateDate(getCourseUpdateDate(info.getId()));
|
||||
|
||||
|
||||
if (!course.isAdaptive()) {
|
||||
String courseType = info.getType();
|
||||
course.setName(info.getName());
|
||||
@@ -216,7 +218,8 @@ public class EduStepicConnector {
|
||||
|
||||
public static List<Lesson> getLessons(int sectionId) throws IOException {
|
||||
final StepicWrappers.SectionContainer
|
||||
sectionContainer = EduStepicClient.getFromStepic(EduStepicNames.SECTIONS + String.valueOf(sectionId), StepicWrappers.SectionContainer.class);
|
||||
sectionContainer =
|
||||
EduStepicClient.getFromStepic(EduStepicNames.SECTIONS + String.valueOf(sectionId), StepicWrappers.SectionContainer.class);
|
||||
List<Integer> unitIds = sectionContainer.sections.get(0).units;
|
||||
final List<Lesson> lessons = new ArrayList<>();
|
||||
for (Integer unitId : unitIds) {
|
||||
@@ -224,14 +227,16 @@ public class EduStepicConnector {
|
||||
unit = EduStepicClient.getFromStepic(EduStepicNames.UNITS + "/" + String.valueOf(unitId), StepicWrappers.UnitContainer.class);
|
||||
int lessonID = unit.units.get(0).lesson;
|
||||
StepicWrappers.LessonContainer
|
||||
lessonContainer = EduStepicClient.getFromStepic(EduStepicNames.LESSONS + String.valueOf(lessonID), StepicWrappers.LessonContainer.class);
|
||||
lessonContainer =
|
||||
EduStepicClient.getFromStepic(EduStepicNames.LESSONS + String.valueOf(lessonID), StepicWrappers.LessonContainer.class);
|
||||
Lesson lesson = lessonContainer.lessons.get(0);
|
||||
lesson.taskList = new ArrayList<>();
|
||||
for (Integer s : lesson.steps) {
|
||||
createTask(lesson, s);
|
||||
}
|
||||
if (!lesson.taskList.isEmpty())
|
||||
if (!lesson.taskList.isEmpty()) {
|
||||
lessons.add(lesson);
|
||||
}
|
||||
}
|
||||
|
||||
return lessons;
|
||||
@@ -260,7 +265,8 @@ public class EduStepicConnector {
|
||||
}
|
||||
|
||||
public static StepicWrappers.StepSource getStep(Integer step) throws IOException {
|
||||
return EduStepicClient.getFromStepic(EduStepicNames.STEPS + "/" + String.valueOf(step), StepicWrappers.StepContainer.class).steps.get(0);
|
||||
return EduStepicClient.getFromStepic(EduStepicNames.STEPS + "/" + String.valueOf(step), StepicWrappers.StepContainer.class).steps
|
||||
.get(0);
|
||||
}
|
||||
|
||||
public static void postAttempt(@NotNull final Task task, boolean passed, @NotNull final Project project) {
|
||||
@@ -282,7 +288,8 @@ public class EduStepicConnector {
|
||||
if (statusLine.getStatusCode() != HttpStatus.SC_CREATED) {
|
||||
LOG.warn("Failed to make attempt " + attemptResponseString);
|
||||
}
|
||||
final StepicWrappers.AttemptWrapper.Attempt attempt = new Gson().fromJson(attemptResponseString, StepicWrappers.AttemptContainer.class).attempts.get(0);
|
||||
final StepicWrappers.AttemptWrapper.Attempt attempt =
|
||||
new Gson().fromJson(attemptResponseString, StepicWrappers.AttemptContainer.class).attempts.get(0);
|
||||
|
||||
final Map<String, TaskFile> taskFiles = task.getTaskFiles();
|
||||
final ArrayList<StepicWrappers.SolutionFile> files = new ArrayList<>();
|
||||
|
||||
+11
-27
@@ -2,16 +2,15 @@ package com.jetbrains.edu.coursecreator;
|
||||
|
||||
import com.intellij.ide.fileTemplates.FileTemplate;
|
||||
import com.intellij.ide.fileTemplates.FileTemplateManager;
|
||||
import com.intellij.ide.fileTemplates.FileTemplateUtil;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.fileEditor.FileDocumentManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.io.FileUtilRt;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.DocumentUtil;
|
||||
import com.jetbrains.edu.learning.StudyTaskManager;
|
||||
import com.intellij.psi.PsiDirectory;
|
||||
import com.intellij.psi.PsiManager;
|
||||
import com.jetbrains.edu.learning.core.EduNames;
|
||||
import com.jetbrains.edu.learning.courseFormat.Task;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -69,38 +68,23 @@ public class PyCCLanguageManager implements CCLanguageManager {
|
||||
if (taskDir == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
int prevSubtaskIndex = task.getLastSubtaskIndex();
|
||||
String name = prevSubtaskIndex == 0 ? EduNames.TESTS_FILE : getSubtaskTestsFileName(prevSubtaskIndex);
|
||||
VirtualFile testsFile = taskDir.findChild(name);
|
||||
if (testsFile == null) {
|
||||
return;
|
||||
}
|
||||
Document document = FileDocumentManager.getInstance().getDocument(testsFile);
|
||||
if (document == null) {
|
||||
return;
|
||||
}
|
||||
CharSequence prevTestText = document.getCharsSequence();
|
||||
int nextSubtaskIndex = prevSubtaskIndex + 1;
|
||||
int nextSubtaskIndex = task.getLastSubtaskIndex() + 1;
|
||||
String nextSubtaskTestsFileName = getSubtaskTestsFileName(nextSubtaskIndex);
|
||||
ApplicationManager.getApplication().runWriteAction(() -> {
|
||||
try {
|
||||
VirtualFile nextSubtaskTestsFile = taskDir.createChildData(this, nextSubtaskTestsFileName);
|
||||
StudyTaskManager.getInstance(project).addInvisibleFiles(nextSubtaskTestsFile.getPath());
|
||||
Document nextSubtaskDocument = FileDocumentManager.getInstance().getDocument(nextSubtaskTestsFile);
|
||||
if (nextSubtaskDocument == null) {
|
||||
PsiDirectory taskPsiDir = PsiManager.getInstance(project).findDirectory(taskDir);
|
||||
FileTemplate testsTemplate = getTestsTemplate(project);
|
||||
if (taskPsiDir == null || testsTemplate == null) {
|
||||
return;
|
||||
}
|
||||
String header = "# This is test for subtask " + nextSubtaskIndex + ". We've already copied tests from previous subtask here.\n\n";
|
||||
DocumentUtil.writeInRunUndoTransparentAction(() -> {
|
||||
nextSubtaskDocument.insertString(0, header);
|
||||
nextSubtaskDocument.insertString(header.length(), prevTestText);
|
||||
FileDocumentManager.getInstance().saveDocument(nextSubtaskDocument);
|
||||
});
|
||||
FileTemplateUtil.createFromTemplate(testsTemplate, nextSubtaskTestsFileName, null, taskPsiDir);
|
||||
}
|
||||
catch (IOException e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
catch (Exception e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user