Added inner directories support to the educational edition

This commit is contained in:
Ekaterina Tuzova
2016-11-22 18:23:22 +03:00
parent 986a98eee1
commit 0935834d85
35 changed files with 247 additions and 104 deletions

View File

@@ -50,20 +50,20 @@ public class CCRefactoringElementListenerProvider implements RefactoringElementL
static class CCRenameListener extends RefactoringElementAdapter {
private String myElementName;
private String myElementRelativePath;
public CCRenameListener(PsiElement element) {
if (element instanceof PsiFile) {
PsiFile psiFile = (PsiFile)element;
myElementName = psiFile.getName();
myElementRelativePath = StudyUtils.pathRelativeToTask(psiFile.getVirtualFile());
}
}
@Override
protected void elementRenamedOrMoved(@NotNull PsiElement newElement) {
if (newElement instanceof PsiFile && myElementName != null) {
if (newElement instanceof PsiFile && myElementRelativePath != null) {
PsiFile psiFile = (PsiFile)newElement;
tryToRenameTaskFile(psiFile, myElementName);
tryToRenameTaskFile(psiFile, myElementRelativePath);
}
}
@@ -107,7 +107,7 @@ public class CCRefactoringElementListenerProvider implements RefactoringElementL
});
taskFiles.remove(oldName);
taskFiles.put(file.getName(), taskFile);
taskFiles.put(StudyUtils.pathRelativeToTask(file.getVirtualFile()), taskFile);
CCUtils.createResourceFile(file.getVirtualFile(), course, taskDir.getVirtualFile());
}

View File

@@ -266,7 +266,7 @@ public class CCUtils {
}
for (Map.Entry<String, TaskFile> entry : task.getTaskFiles().entrySet()) {
String name = entry.getKey();
VirtualFile answerFile = taskDir.findChild(name);
VirtualFile answerFile = taskDir.findFileByRelativePath(name);
if (answerFile == null) {
continue;
}

View File

@@ -44,7 +44,7 @@ public class CCVirtualFileListener extends VirtualFileAdapter {
return;
}
String name = createdFile.getName();
String taskRelativePath = StudyUtils.pathRelativeToTask(createdFile);
CCLanguageManager manager = CCUtils.getStudyLanguageManager(course);
if (manager != null && manager.doNotPackFile(new File(createdFile.getPath()))) {
@@ -52,10 +52,10 @@ public class CCVirtualFileListener extends VirtualFileAdapter {
}
if (CCUtils.isTestsFile(project, createdFile)
|| StudyUtils.isTaskDescriptionFile(name)
|| name.contains(EduNames.WINDOW_POSTFIX)
|| name.contains(EduNames.WINDOWS_POSTFIX)
|| name.contains(EduNames.ANSWERS_POSTFIX)) {
|| StudyUtils.isTaskDescriptionFile(taskRelativePath)
|| taskRelativePath.contains(EduNames.WINDOW_POSTFIX)
|| taskRelativePath.contains(EduNames.WINDOWS_POSTFIX)
|| taskRelativePath.contains(EduNames.ANSWERS_POSTFIX)) {
return;
}
VirtualFile taskVF = StudyUtils.getTaskDir(createdFile);
@@ -69,7 +69,7 @@ public class CCVirtualFileListener extends VirtualFileAdapter {
CCUtils.createResourceFile(createdFile, course, taskVF);
task.addTaskFile(name, 1);
task.addTaskFile(taskRelativePath, 1);
}
@Override
@@ -136,6 +136,6 @@ public class CCVirtualFileListener extends VirtualFileAdapter {
if (task == null) {
return;
}
task.getTaskFiles().remove(removedTaskFile.getName());
task.getTaskFiles().remove(StudyUtils.pathRelativeToTask(removedTaskFile));
}
}

View File

@@ -55,8 +55,9 @@ public class CCAddAsTaskFile extends CCTaskFileActionBase {
if (myTaskFile != null) {
myTask.addTaskFile(myTaskFile);
} else {
myTask.addTaskFile(myFile.getName(), myTask.getTaskFiles().size());
myTaskFile = myTask.getTaskFile(myFile.getName());
final String taskRelativePath = StudyUtils.pathRelativeToTask(myFile);
myTask.addTaskFile(taskRelativePath, myTask.getTaskFiles().size());
myTaskFile = myTask.getTaskFile(taskRelativePath);
}
CCUtils.createResourceFile(myFile, myCourse, StudyUtils.getTaskDir(myFile));
ProjectView.getInstance(myProject).refresh();

View File

@@ -137,7 +137,7 @@ public class CCCreateCourseArchive extends DumbAwareAction {
transformSubtaskTestsToTextFiles(studentFileDir);
}
for (String taskFile : task.getTaskFiles().keySet()) {
VirtualFile answerFile = taskDir.findChild(taskFile);
VirtualFile answerFile = taskDir.findFileByRelativePath(taskFile);
if (answerFile == null) {
continue;
}

View File

@@ -130,7 +130,7 @@ public class CCFromCourseArchive extends DumbAwareAction {
@NotNull final Map.Entry<String, TaskFile> taskFileEntry) {
final String name = taskFileEntry.getKey();
final TaskFile taskFile = taskFileEntry.getValue();
VirtualFile file = userFileDir.findChild(name);
VirtualFile file = userFileDir.findFileByRelativePath(name);
assert file != null;
final Document originDocument = FileDocumentManager.getInstance().getDocument(file);
if (originDocument == null) {

View File

@@ -58,7 +58,7 @@ public class CCHideFromStudent extends CCTaskFileActionBase {
@Override
public void undo() throws UnexpectedUndoException {
myTask.getTaskFiles().put(myFile.getName(), myTaskFile);
myTask.getTaskFiles().put(StudyUtils.pathRelativeToTask(myFile), myTaskFile);
CCUtils.createResourceFile(myFile, myCourse, StudyUtils.getTaskDir(myFile));
if (!myTaskFile.getAnswerPlaceholders().isEmpty() && FileEditorManager.getInstance(myProject).isFileOpen(myFile)) {
for (FileEditor fileEditor : FileEditorManager.getInstance(myProject).getEditors(myFile)) {
@@ -92,8 +92,8 @@ public class CCHideFromStudent extends CCTaskFileActionBase {
}
}
}
String name = file.getName();
VirtualFile patternFile = StudyUtils.getPatternFile(taskFile, name);
String taskRelativePath = StudyUtils.pathRelativeToTask(file);
VirtualFile patternFile = StudyUtils.getPatternFile(taskFile, taskRelativePath);
ApplicationManager.getApplication().runWriteAction(() -> {
if (patternFile != null) {
try {
@@ -104,7 +104,7 @@ public class CCHideFromStudent extends CCTaskFileActionBase {
}
}
});
taskFiles.remove(name);
taskFiles.remove(taskRelativePath);
}
@Override

View File

@@ -1,6 +1,7 @@
package com.jetbrains.edu.coursecreator.projectView;
import com.intellij.ide.projectView.ViewSettings;
import com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode;
import com.intellij.ide.projectView.impl.nodes.PsiFileNode;
import com.intellij.ide.util.treeView.AbstractTreeNode;
import com.intellij.openapi.project.Project;
@@ -11,7 +12,6 @@ import com.jetbrains.edu.learning.courseFormat.Course;
import com.jetbrains.edu.learning.courseFormat.Lesson;
import com.jetbrains.edu.learning.courseFormat.StudyItem;
import com.jetbrains.edu.learning.projectView.CourseDirectoryNode;
import com.jetbrains.edu.learning.projectView.StudyDirectoryNode;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -45,7 +45,7 @@ public class CCCourseDirectoryNode extends CourseDirectoryNode {
}
@Override
public StudyDirectoryNode createChildDirectoryNode(StudyItem item, PsiDirectory directory) {
public PsiDirectoryNode createChildDirectoryNode(StudyItem item, PsiDirectory directory) {
return new CCLessonDirectoryNode(myProject, directory, myViewSettings, ((Lesson)item));
}
}

View File

@@ -0,0 +1,62 @@
package com.jetbrains.edu.coursecreator.projectView;
import com.intellij.ide.projectView.ViewSettings;
import com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode;
import com.intellij.ide.util.treeView.AbstractTreeNode;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiDirectory;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.jetbrains.edu.coursecreator.CCUtils;
import com.jetbrains.edu.learning.StudyLanguageManager;
import com.jetbrains.edu.learning.StudyTaskManager;
import com.jetbrains.edu.learning.StudyUtils;
import com.jetbrains.edu.learning.courseFormat.Course;
import com.jetbrains.edu.learning.courseFormat.StudyItem;
import com.jetbrains.edu.learning.projectView.DirectoryNode;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class CCDirectoryNode extends DirectoryNode {
public CCDirectoryNode(@NotNull Project project,
PsiDirectory value,
ViewSettings viewSettings) {
super(project, value, viewSettings);
}
@Override
public boolean canNavigate() {
return true;
}
@Nullable
@Override
public AbstractTreeNode modifyChildNode(AbstractTreeNode childNode) {
final AbstractTreeNode node = super.modifyChildNode(childNode);
if (node != null) return node;
Object value = childNode.getValue();
if (value instanceof PsiElement) {
PsiFile psiFile = ((PsiElement) value).getContainingFile();
VirtualFile virtualFile = psiFile.getVirtualFile();
Course course = StudyTaskManager.getInstance(myProject).getCourse();
if (course == null) {
return null;
}
StudyLanguageManager manager = StudyUtils.getLanguageManager(course);
if (manager == null) {
return new CCStudentInvisibleFileNode(myProject, psiFile, myViewSettings);
}
if (!CCUtils.isTestsFile(myProject, virtualFile)) {
return new CCStudentInvisibleFileNode(myProject, psiFile, myViewSettings);
}
}
return null;
}
@Override
public PsiDirectoryNode createChildDirectoryNode(StudyItem item, PsiDirectory value) {
return new CCDirectoryNode(myProject, value, myViewSettings);
}
}

View File

@@ -1,13 +1,13 @@
package com.jetbrains.edu.coursecreator.projectView;
import com.intellij.ide.projectView.ViewSettings;
import com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiDirectory;
import com.jetbrains.edu.learning.courseFormat.Lesson;
import com.jetbrains.edu.learning.courseFormat.StudyItem;
import com.jetbrains.edu.learning.courseFormat.Task;
import com.jetbrains.edu.learning.projectView.LessonDirectoryNode;
import com.jetbrains.edu.learning.projectView.StudyDirectoryNode;
import org.jetbrains.annotations.NotNull;
public class CCLessonDirectoryNode extends LessonDirectoryNode {
@@ -19,7 +19,7 @@ public class CCLessonDirectoryNode extends LessonDirectoryNode {
}
@Override
public StudyDirectoryNode createChildDirectoryNode(StudyItem item, PsiDirectory directory) {
public PsiDirectoryNode createChildDirectoryNode(StudyItem item, PsiDirectory directory) {
return new CCTaskDirectoryNode(myProject, directory, myViewSettings, ((Task)item));
}
}

View File

@@ -1,6 +1,7 @@
package com.jetbrains.edu.coursecreator.projectView;
import com.intellij.ide.projectView.ViewSettings;
import com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode;
import com.intellij.ide.util.treeView.AbstractTreeNode;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
@@ -14,6 +15,7 @@ import com.jetbrains.edu.learning.StudyTaskManager;
import com.jetbrains.edu.learning.StudyUtils;
import com.jetbrains.edu.learning.core.EduNames;
import com.jetbrains.edu.learning.courseFormat.Course;
import com.jetbrains.edu.learning.courseFormat.StudyItem;
import com.jetbrains.edu.learning.courseFormat.Task;
import com.jetbrains.edu.learning.projectView.TaskDirectoryNode;
import org.jetbrains.annotations.NotNull;
@@ -95,4 +97,9 @@ public class CCTaskDirectoryNode extends TaskDirectoryNode {
int stepIndex = Integer.valueOf(nameWithoutExtension.substring(EduNames.SUBTASK_MARKER.length() + stepMarkerStart));
return stepIndex == myTask.getActiveSubtaskIndex();
}
@Override
public PsiDirectoryNode createChildDirectoryNode(StudyItem item, PsiDirectory value) {
return new CCDirectoryNode(myProject, value, myViewSettings);
}
}

View File

@@ -51,7 +51,7 @@ public abstract class StudyBasePluginConfigurator implements StudyPluginConfigur
@Override
public void fileOpened(@NotNull FileEditorManager source, @NotNull VirtualFile file) {
Task task = getTask(file);
setTaskText(task, file.getParent());
setTaskText(task, StudyUtils.getTaskDir(file));
}
@Override
@@ -69,7 +69,7 @@ public abstract class StudyBasePluginConfigurator implements StudyPluginConfigur
VirtualFile file = event.getNewFile();
if (file != null) {
Task task = getTask(file);
setTaskText(task, file.getParent());
setTaskText(task, StudyUtils.getTaskDir(file));
}
toolWindow.setBottomComponent(null);
}

View File

@@ -224,7 +224,7 @@ public class StudyProjectComponent implements ProjectComponent {
private static void copyFile(@NotNull final File from, @NotNull final File to) {
if (from.exists()) {
try {
FileUtil.copy(from, to);
FileUtil.copyFileOrDir(from, to);
}
catch (IOException e) {
LOG.warn("Failed to copy " + from.getName());
@@ -326,7 +326,7 @@ public class StudyProjectComponent implements ProjectComponent {
public void fileCreated(@NotNull VirtualFileEvent event) {
if (myProject.isDisposed()) return;
final VirtualFile createdFile = event.getFile();
final VirtualFile taskDir = createdFile.getParent();
final VirtualFile taskDir = StudyUtils.getTaskDir(createdFile);
final Course course = StudyTaskManager.getInstance(myProject).getCourse();
if (course == null || !EduNames.STUDY.equals(course.getCourseMode())) {
return;
@@ -345,7 +345,7 @@ public class StudyProjectComponent implements ProjectComponent {
final TaskFile taskFile = new TaskFile();
taskFile.initTaskFile(task, false);
taskFile.setUserCreated(true);
final String name = createdFile.getName();
final String name = FileUtil.getRelativePath(taskDir.getPath(), createdFile.getPath(), File.separatorChar);
taskFile.name = name;
//TODO: put to other steps as well
task.getTaskFiles().put(name, taskFile);

View File

@@ -21,7 +21,7 @@ public class StudyState {
myEditor = studyEditor != null ? studyEditor.getEditor() : null;
myTaskFile = studyEditor != null ? studyEditor.getTaskFile() : null;
myVirtualFile = myEditor != null ? FileDocumentManager.getInstance().getFile(myEditor.getDocument()) : null;
myTaskDir = myVirtualFile != null ? myVirtualFile.getParent() : null;
myTaskDir = myVirtualFile != null ? StudyUtils.getTaskDir(myVirtualFile) : null;
myTask = myTaskFile != null ? myTaskFile.getTask() : null;
}

View File

@@ -49,7 +49,7 @@ public class StudySubtaskUtils {
int fromSubtaskIndex = task.getActiveSubtaskIndex();
for (Map.Entry<String, TaskFile> entry : task.getTaskFiles().entrySet()) {
String name = entry.getKey();
VirtualFile virtualFile = taskDir.findChild(name);
VirtualFile virtualFile = taskDir.findFileByRelativePath(name);
if (virtualFile == null) {
continue;
}

View File

@@ -82,7 +82,6 @@ public class StudyUtils {
}
private static final Logger LOG = Logger.getInstance(StudyUtils.class.getName());
private static final String EMPTY_TASK_TEXT = "Please, open any task to see task description";
private static final String ourPrefix = "<html><head><script type=\"text/x-mathjax-config\">\n" +
" MathJax.Hub.Config({\n" +
" tex2jax: {\n" +
@@ -315,7 +314,7 @@ public class StudyUtils {
if (course == null) {
return null;
}
VirtualFile taskDir = file.getParent();
VirtualFile taskDir = getTaskDir(file);
if (taskDir == null) {
return null;
}
@@ -342,7 +341,7 @@ public class StudyUtils {
return null;
}
final Task task = tasks.get(taskIndex);
return task.getFile(file.getName());
return task.getFile(pathRelativeToTask(file));
}
}
return null;
@@ -483,14 +482,6 @@ public class StudyUtils {
return null;
}
final Course course = task.getLesson().getCourse();
String text = task.getText() != null ? task.getText() : getTaskTextFromTaskName(taskDirectory, EduNames.TASK_MD);
if (text == null) return null;
if (course.isAdaptive()) text = wrapAdaptiveCourseText(text);
if (text != null && !text.isEmpty()) {
return wrapTextToDisplayLatex(text);
}
if (taskDirectory != null) {
String fileNameWithoutExtension = FileUtil.getNameWithoutExtension(EduNames.TASK_HTML);
int activeStepIndex = task.getActiveSubtaskIndex();
@@ -501,7 +492,16 @@ public class StudyUtils {
if (taskTextFileHtml != null) return wrapTextToDisplayLatex(taskTextFileHtml);
final String taskTextFileMd = getTaskTextFromTaskName(taskDirectory, getTaskDescriptionName(fileNameWithoutExtension, EduNames.TASK_MD));
if (taskTextFileMd != null) return wrapTextToDisplayLatex(convertToHtml(taskTextFileMd));
if (taskTextFileMd != null) return wrapTextToDisplayLatex(convertToHtml(taskTextFileMd));
}
String text = task.getText() != null ? task.getText() : getTaskTextFromTaskName(taskDirectory, EduNames.TASK_MD);
if (text == null) return null;
if (course.isAdaptive()) text = wrapAdaptiveCourseText(text);
if (!text.isEmpty()) {
return wrapTextToDisplayLatex(text);
}
return null;
}
@@ -523,8 +523,7 @@ public class StudyUtils {
@Nullable
private static String getTaskTextFromTaskName(@Nullable VirtualFile taskDirectory, @NotNull String taskTextFilename) {
if (taskDirectory == null) return null;
VirtualFile taskTextFile = ObjectUtils.chooseNotNull(taskDirectory.findChild(EduNames.TASK_HTML),
taskDirectory.findChild(EduNames.TASK_MD));
VirtualFile taskTextFile = taskDirectory.findChild(taskTextFilename);
if (taskTextFile == null) {
VirtualFile srcDir = taskDirectory.findChild(EduNames.SRC);
if (srcDir != null) {
@@ -563,7 +562,7 @@ public class StudyUtils {
public static String getTaskText(@NotNull final Project project) {
TaskFile taskFile = getSelectedTaskFile(project);
if (taskFile == null) {
return EMPTY_TASK_TEXT;
return StudyToolWindow.EMPTY_TASK_TEXT;
}
final Task task = taskFile.getTask();
if (task != null) {
@@ -658,15 +657,18 @@ public class StudyUtils {
@Nullable
public static VirtualFile getTaskDir(@NotNull VirtualFile taskFile) {
VirtualFile parent = taskFile.getParent();
if (parent == null) {
return null;
}
String name = parent.getName();
if (name.contains(EduNames.TASK)) {
return parent;
}
if (EduNames.SRC.equals(name)) {
return parent.getParent();
while (parent != null) {
String name = parent.getName();
if (name.contains(EduNames.TASK) && parent.isDirectory()) {
return parent;
}
if (EduNames.SRC.equals(name)) {
return parent.getParent();
}
parent = parent.getParent();
}
return null;
}
@@ -808,4 +810,10 @@ public class StudyUtils {
}
return null;
}
public static String pathRelativeToTask(VirtualFile file) {
VirtualFile taskDir = getTaskDir(file);
if (taskDir == null) return file.getName();
return FileUtil.getRelativePath(taskDir.getPath(), file.getPath(), File.separatorChar);
}
}

View File

@@ -20,12 +20,12 @@ import com.intellij.ui.tabs.TabInfo;
import com.intellij.ui.tabs.TabsListener;
import com.intellij.ui.tabs.impl.JBEditorTabs;
import com.intellij.util.PlatformIcons;
import com.jetbrains.edu.learning.StudyTaskManager;
import com.jetbrains.edu.learning.StudyUtils;
import com.jetbrains.edu.learning.core.EduNames;
import com.jetbrains.edu.learning.core.EduUtils;
import com.jetbrains.edu.learning.courseFormat.Task;
import com.jetbrains.edu.learning.courseFormat.TaskFile;
import com.jetbrains.edu.learning.StudyTaskManager;
import com.jetbrains.edu.learning.StudyUtils;
import com.jetbrains.edu.learning.courseFormat.UserTest;
import com.jetbrains.edu.learning.editor.StudyEditor;
import com.jetbrains.edu.learning.ui.StudyTestContentPanel;
@@ -67,7 +67,7 @@ public class StudyEditInputAction extends DumbAwareAction {
public void selectionChanged(TabInfo oldSelection, TabInfo newSelection) {
if (newSelection.getIcon() != null) {
int tabCount = tabbedPane.getTabCount();
VirtualFile taskDir = openedFile.getParent();
VirtualFile taskDir = StudyUtils.getTaskDir(openedFile);
VirtualFile testsDir = taskDir.findChild(EduNames.USER_TESTS);
assert testsDir != null;
UserTest userTest = createUserTest(testsDir, currentTask, studyTaskManager);

View File

@@ -216,7 +216,7 @@ public class StudyCheckTask extends com.intellij.openapi.progress.Task.Backgroun
}
for (Map.Entry<String, TaskFile> entry : myTask.getTaskFiles().entrySet()) {
TaskFile taskFile = entry.getValue();
VirtualFile virtualFile = taskDir.findChild(entry.getKey());
VirtualFile virtualFile = taskDir.findFileByRelativePath(entry.getKey());
if (virtualFile == null) {
continue;
}

View File

@@ -52,7 +52,7 @@ public class StudyCheckUtils {
for (Map.Entry<String, TaskFile> entry : task.getTaskFiles().entrySet()) {
String name = entry.getKey();
TaskFile taskFile = entry.getValue();
VirtualFile virtualFile = taskDir.findChild(name);
VirtualFile virtualFile = taskDir.findFileByRelativePath(name);
if (virtualFile == null) {
continue;
}
@@ -79,7 +79,7 @@ public class StudyCheckUtils {
TaskFile taskFile = entry.getValue();
if (taskManager.hasFailedAnswerPlaceholders(taskFile)) {
taskFileToNavigate = taskFile;
VirtualFile virtualFile = taskDir.findChild(name);
VirtualFile virtualFile = taskDir.findFileByRelativePath(name);
if (virtualFile == null) {
continue;
}
@@ -117,7 +117,7 @@ public class StudyCheckUtils {
@NotNull final String taskFileName,
@NotNull final TaskFile taskFile,
@NotNull final Project project) {
final VirtualFile virtualFile = taskDir.findChild(taskFileName);
final VirtualFile virtualFile = taskDir.findFileByRelativePath(taskFileName);
if (virtualFile == null) {
return;
}
@@ -147,7 +147,7 @@ public class StudyCheckUtils {
final FileDocumentManager documentManager = FileDocumentManager.getInstance();
final Document document = documentManager.getDocument(answerFile);
if (document != null) {
TaskFile answerTaskFile = source.getTask().copy().getTaskFile(file.getName());
TaskFile answerTaskFile = source.getTask().copy().getTaskFile(StudyUtils.pathRelativeToTask(file));
if (answerTaskFile == null) {
return null;
}
@@ -185,7 +185,7 @@ public class StudyCheckUtils {
for (Map.Entry<String, TaskFile> entry : task.getTaskFiles().entrySet()) {
String name = entry.getKey();
TaskFile taskFile = entry.getValue();
VirtualFile virtualFile = taskDir.findChild(name);
VirtualFile virtualFile = taskDir.findFileByRelativePath(name);
if (virtualFile == null) {
continue;
}

View File

@@ -10,6 +10,8 @@ import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.vfs.VirtualFile;
import com.jetbrains.edu.learning.StudyTaskManager;
import com.jetbrains.edu.learning.StudyUtils;
import com.jetbrains.edu.learning.core.EduDocumentListener;
import com.jetbrains.edu.learning.core.EduNames;
import com.jetbrains.edu.learning.core.EduUtils;
@@ -17,8 +19,6 @@ import com.jetbrains.edu.learning.courseFormat.AnswerPlaceholder;
import com.jetbrains.edu.learning.courseFormat.Course;
import com.jetbrains.edu.learning.courseFormat.StudyStatus;
import com.jetbrains.edu.learning.courseFormat.TaskFile;
import com.jetbrains.edu.learning.StudyTaskManager;
import com.jetbrains.edu.learning.StudyUtils;
import org.jetbrains.annotations.NotNull;
import java.io.File;
@@ -50,7 +50,7 @@ public class StudySmartChecker {
if (windowDocument != null) {
final File resourceFile =
StudyUtils.copyResourceFile(virtualFile.getName(), windowCopy.getName(), project, usersTaskFile.getTask());
TaskFile windowTaskFile = answerTaskFile.getTask().copy().getTaskFile(virtualFile.getName());
TaskFile windowTaskFile = answerTaskFile.getTask().copy().getTaskFile(StudyUtils.pathRelativeToTask(virtualFile));
if (windowTaskFile == null) {
return;
}

View File

@@ -16,7 +16,7 @@ import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.psi.PsiDirectory;
@@ -124,16 +124,16 @@ public class EduUtils {
if (document != null) {
FileDocumentManager.getInstance().saveDocument(document);
}
String name = file.getName();
String taskRelativePath = StudyUtils.pathRelativeToTask(file);
try {
VirtualFile userFile = toDir.findChild(name);
VirtualFile userFile = toDir.findFileByRelativePath(taskRelativePath);
if (userFile != null) {
userFile.delete(requestor);
}
return VfsUtilCore.copyFile(requestor, file, toDir);
return VfsUtil.copyFileRelative(requestor, file, toDir, taskRelativePath);
}
catch (IOException e) {
LOG.info("Failed to create file " + name + " in folder " + toDir.getPath(), e);
LOG.info("Failed to create file " + taskRelativePath + " in folder " + toDir.getPath(), e);
}
return null;
}
@@ -161,7 +161,7 @@ public class EduUtils {
}
task = task.copy();
}
TaskFile taskFile = task.getTaskFile(answerFile.getName());
TaskFile taskFile = task.getTaskFile(StudyUtils.pathRelativeToTask(answerFile));
if (taskFile == null) {
return null;
}
@@ -210,12 +210,13 @@ public class EduUtils {
public static void deleteWindowDescriptions(@NotNull final Task task, @NotNull final VirtualFile taskDir) {
for (Map.Entry<String, TaskFile> entry : task.getTaskFiles().entrySet()) {
String name = entry.getKey();
VirtualFile virtualFile = taskDir.findChild(name);
VirtualFile virtualFile = taskDir.findFileByRelativePath(name);
if (virtualFile == null) {
continue;
}
String windowsFileName = virtualFile.getNameWithoutExtension() + EduNames.WINDOWS_POSTFIX;
deleteWindowsFile(taskDir, windowsFileName);
VirtualFile parentDir = virtualFile.getParent();
deleteWindowsFile(parentDir, windowsFileName);
}
}

View File

@@ -34,13 +34,9 @@ public class StudyGenerator {
public static void createTaskFile(@NotNull final VirtualFile taskDir, @NotNull final File resourceRoot,
@NotNull final String name) throws IOException {
String systemIndependentName = FileUtil.toSystemIndependentName(name);
final int index = systemIndependentName.lastIndexOf("/");
if (index > 0) {
systemIndependentName = systemIndependentName.substring(index + 1);
}
File resourceFile = new File(resourceRoot, name);
File fileInProject = new File(taskDir.getPath(), systemIndependentName);
FileUtil.copy(resourceFile, fileInProject);
FileUtil.copyFileOrDir(resourceFile, fileInProject);
}
/**
@@ -65,7 +61,7 @@ public class StudyGenerator {
if (filesInTask != null) {
for (File file : filesInTask) {
String fileName = file.getName();
if (!task.isTaskFile(fileName)) {
if (!task.isTaskFile(fileName) && !file.isDirectory()) {
File resourceFile = new File(newResourceRoot, fileName);
File fileInProject = new File(taskDir.getCanonicalPath(), fileName);
FileUtil.copy(resourceFile, fileInProject);

View File

@@ -16,6 +16,7 @@ import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.openapi.vfs.newvfs.NewVirtualFile;
@@ -181,7 +182,8 @@ public class StudyProjectGenerator {
for (Map.Entry<String, TaskFile> entry : taskFiles.entrySet()) {
final String name = entry.getKey();
final TaskFile taskFile = entry.getValue();
final VirtualFile virtualFile = ((VirtualDirectoryImpl)taskDir).refreshAndFindChild(name);
taskDir.refresh(false, true);
final VirtualFile virtualFile = VfsUtil.findRelativeFile(taskDir, name);
if (virtualFile != null) {
FileEditorManager.getInstance(project).openFile(virtualFile, true);
if (!taskFile.getActivePlaceholders().isEmpty()) {

View File

@@ -114,7 +114,7 @@ public class StudyNavigator {
String name = entry.getKey();
TaskFile taskFile = entry.getValue();
VirtualFile srcDir = taskDir.findChild(EduNames.SRC);
VirtualFile vf = srcDir == null ? taskDir.findChild(name) : srcDir.findChild(name);
VirtualFile vf = srcDir == null ? taskDir.findFileByRelativePath(name) : srcDir.findFileByRelativePath(name);
if (vf != null) {
if (fileToActivate != null) {
FileEditorManager.getInstance(project).openFile(vf, true);
@@ -171,7 +171,7 @@ public class StudyNavigator {
return;
}
for (String name : nextTaskFiles.keySet()) {
VirtualFile virtualFile = taskDir.findChild(name);
VirtualFile virtualFile = taskDir.findFileByRelativePath(name);
if (virtualFile == null) {
continue;
}

View File

@@ -2,6 +2,7 @@ package com.jetbrains.edu.learning.projectView;
import com.intellij.ide.projectView.PresentationData;
import com.intellij.ide.projectView.ViewSettings;
import com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode;
import com.intellij.ide.util.treeView.AbstractTreeNode;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiDirectory;
@@ -49,7 +50,7 @@ public class CourseDirectoryNode extends StudyDirectoryNode {
}
@Override
public StudyDirectoryNode createChildDirectoryNode(StudyItem item, PsiDirectory directory) {
public PsiDirectoryNode createChildDirectoryNode(StudyItem item, PsiDirectory directory) {
return new LessonDirectoryNode(myProject, directory, myViewSettings, (Lesson)item);
}
}

View File

@@ -0,0 +1,57 @@
package com.jetbrains.edu.learning.projectView;
import com.intellij.ide.projectView.ViewSettings;
import com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode;
import com.intellij.ide.util.treeView.AbstractTreeNode;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiDirectory;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.jetbrains.edu.learning.StudyUtils;
import com.jetbrains.edu.learning.courseFormat.StudyItem;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class DirectoryNode extends StudyDirectoryNode {
@NotNull protected final Project myProject;
protected final ViewSettings myViewSettings;
public DirectoryNode(@NotNull Project project,
PsiDirectory value,
ViewSettings viewSettings) {
super(project, value, viewSettings);
myProject = project;
myViewSettings = viewSettings;
}
@Override
public boolean canNavigate() {
return true;
}
@Nullable
@Override
public AbstractTreeNode modifyChildNode(AbstractTreeNode childNode) {
Object value = childNode.getValue();
if (value instanceof PsiDirectory) {
return createChildDirectoryNode(null, (PsiDirectory)value);
}
if (value instanceof PsiElement) {
PsiFile psiFile = ((PsiElement) value).getContainingFile();
if (psiFile == null) return null;
VirtualFile virtualFile = psiFile.getVirtualFile();
if (virtualFile == null) {
return null;
}
return StudyUtils.getTaskFile(myProject, virtualFile) != null ? childNode : null;
}
return null;
}
@Override
public PsiDirectoryNode createChildDirectoryNode(StudyItem item, PsiDirectory value) {
return new DirectoryNode(myProject, value, myViewSettings);
}
}

View File

@@ -2,6 +2,7 @@ package com.jetbrains.edu.learning.projectView;
import com.intellij.ide.projectView.PresentationData;
import com.intellij.ide.projectView.ViewSettings;
import com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode;
import com.intellij.ide.util.treeView.AbstractTreeNode;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
@@ -71,7 +72,7 @@ public class LessonDirectoryNode extends StudyDirectoryNode {
}
@Override
public StudyDirectoryNode createChildDirectoryNode(StudyItem item, PsiDirectory directory) {
public PsiDirectoryNode createChildDirectoryNode(StudyItem item, PsiDirectory directory) {
return new TaskDirectoryNode(myProject, directory, myViewSettings, ((Task)item));
}
}

View File

@@ -2,6 +2,7 @@ package com.jetbrains.edu.learning.projectView;
import com.intellij.ide.projectView.PresentationData;
import com.intellij.ide.projectView.ViewSettings;
import com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode;
import com.intellij.ide.util.treeView.AbstractTreeNode;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiDirectory;
@@ -25,7 +26,7 @@ public class SandboxDirectoryNode extends StudyDirectoryNode {
}
@Override
public StudyDirectoryNode createChildDirectoryNode(StudyItem item, PsiDirectory value) {
public PsiDirectoryNode createChildDirectoryNode(StudyItem item, PsiDirectory value) {
return null;
}

View File

@@ -8,7 +8,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiDirectory;
import com.intellij.ui.JBColor;
import com.intellij.ui.SimpleTextAttributes;
import com.jetbrains.edu.learning.courseFormat.*;
import com.jetbrains.edu.learning.courseFormat.StudyItem;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -46,6 +46,6 @@ public abstract class StudyDirectoryNode extends PsiDirectoryNode {
@Nullable
public abstract AbstractTreeNode modifyChildNode(AbstractTreeNode childNode);
public abstract StudyDirectoryNode createChildDirectoryNode(StudyItem item, PsiDirectory value);
public abstract PsiDirectoryNode createChildDirectoryNode(StudyItem item, PsiDirectory value);
}

View File

@@ -2,6 +2,7 @@ package com.jetbrains.edu.learning.projectView;
import com.intellij.ide.projectView.PresentationData;
import com.intellij.ide.projectView.ViewSettings;
import com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode;
import com.intellij.ide.util.treeView.AbstractTreeNode;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
@@ -80,8 +81,12 @@ public class TaskDirectoryNode extends StudyDirectoryNode {
@Override
public AbstractTreeNode modifyChildNode(AbstractTreeNode childNode) {
Object value = childNode.getValue();
if (value instanceof PsiDirectory) {
return createChildDirectoryNode(null, (PsiDirectory)value);
}
if (value instanceof PsiElement) {
PsiFile psiFile = ((PsiElement) value).getContainingFile();
if (psiFile == null) return null;
VirtualFile virtualFile = psiFile.getVirtualFile();
if (virtualFile == null) {
return null;
@@ -92,7 +97,7 @@ public class TaskDirectoryNode extends StudyDirectoryNode {
}
@Override
public StudyDirectoryNode createChildDirectoryNode(StudyItem item, PsiDirectory value) {
return null;
public PsiDirectoryNode createChildDirectoryNode(StudyItem item, PsiDirectory value) {
return new DirectoryNode(myProject, value, myViewSettings);
}
}

View File

@@ -289,10 +289,10 @@ public class EduAdaptiveStepicConnector {
File[] filesInTask = newResourceRoot.listFiles();
if (filesInTask != null) {
for (File file : filesInTask) {
String fileName = file.getName();
if (!task.isTaskFile(fileName)) {
File resourceFile = new File(newResourceRoot, fileName);
File fileInProject = new File(taskDir.getCanonicalPath(), fileName);
String taskRelativePath = FileUtil.getRelativePath(taskDir.getPath(), file.getPath(), File.separatorChar);
if (taskRelativePath != null && !task.isTaskFile(taskRelativePath)) {
File resourceFile = new File(newResourceRoot, taskRelativePath);
File fileInProject = new File(taskDir.getCanonicalPath(), taskRelativePath);
FileUtil.copy(resourceFile, fileInProject);
}
}

View File

@@ -83,7 +83,7 @@ public class StepicWrappers {
return;
}
String name = entry.getKey();
VirtualFile answerFile = taskDir.findChild(name);
VirtualFile answerFile = taskDir.findFileByRelativePath(name);
Pair<VirtualFile, TaskFile> pair = EduUtils.createStudentFile(StepicWrappers.class, project, answerFile, stepicDir, null, 0);
if (pair == null) {
return;

View File

@@ -50,7 +50,7 @@ import java.util.Map;
public abstract class StudyToolWindow extends SimpleToolWindowPanel implements DataProvider, Disposable {
private static final Logger LOG = Logger.getInstance(StudyToolWindow.class);
private static final String TASK_INFO_ID = "taskInfo";
private static final String EMPTY_TASK_TEXT = "Please, open any task to see task description";
public static final String EMPTY_TASK_TEXT = "Please, open any task to see task description";
private final JBCardLayout myCardLayout;
private final JPanel myContentPanel;

View File

@@ -139,12 +139,13 @@ def get_initial_text(path):
Returns the initial task text
"""
course_lib = sys.argv[-2]
test_dir = sys.argv[-3]
import os
# path format is "project_root/lessonX/taskY/file.py"
task_index = path.rfind(os.sep, 0, path.rfind(os.sep))
index = path.rfind(os.sep, 0, task_index)
relative_path = path[index + 1:]
lesson_task = os.sep.join(test_dir.split(os.sep)[-3:-1])
task_dir = os.sep.join(test_dir.split(os.sep)[:-1])
relative_path = lesson_task + os.sep + path[len(task_dir):]
# path format is "project_root/lessonX/taskY/.../file.py"
initial_file_path = os.path.join(course_lib, relative_path)
return get_file_text(initial_file_path)

View File

@@ -139,7 +139,7 @@ public class PyStudyCheckAction extends StudyCheckAction {
for (Map.Entry<String, TaskFile> entry : task.getTaskFiles().entrySet()) {
String name = entry.getKey();
TaskFile taskFile = entry.getValue();
VirtualFile virtualFile = taskDir.findChild(name);
VirtualFile virtualFile = taskDir.findFileByRelativePath(name);
if (virtualFile != null) {
if (!taskFile.getActivePlaceholders().isEmpty()) {
taskVirtualFile = virtualFile;