fixes after IDEA-CR-14348 review

This commit is contained in:
Liana.Bakradze
2016-11-17 17:09:05 +03:00
committed by liana.bakradze
parent 6b360083b6
commit cb304d9c95
20 changed files with 174 additions and 170 deletions
@@ -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++) {
@@ -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;
@@ -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();
}
}
@@ -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) {
@@ -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);
}
@@ -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);
}
}
}
@@ -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) {
@@ -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;
}
}
@@ -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;
@@ -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;
}
@@ -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();
@@ -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);
}
@@ -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) {
@@ -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() {
@@ -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() {
@@ -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);
}
}
@@ -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
@@ -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<>();
@@ -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);
}
});
}