diff --git a/python/educational/course-creator/src/com/jetbrains/edu/coursecreator/CCEditorFactoryListener.java b/python/educational/course-creator/src/com/jetbrains/edu/coursecreator/CCEditorFactoryListener.java index ce2c88f02da2..eeca8d615e03 100644 --- a/python/educational/course-creator/src/com/jetbrains/edu/coursecreator/CCEditorFactoryListener.java +++ b/python/educational/course-creator/src/com/jetbrains/edu/coursecreator/CCEditorFactoryListener.java @@ -44,7 +44,7 @@ public class CCEditorFactoryListener implements EditorFactoryListener { if (taskFile == null) { return; } - TaskFileModificationListener listener = new TaskFileModificationListener(taskFile); + EduDocumentListener listener = new EduDocumentListener(taskFile, true, true); CCProjectService.addDocumentListener(editor.getDocument(), listener); editor.getDocument().addDocumentListener(listener); EditorActionManager.getInstance() @@ -66,17 +66,4 @@ public class CCEditorFactoryListener implements EditorFactoryListener { editor.getMarkupModel().removeAllHighlighters(); editor.getSelectionModel().removeSelection(); } - - private static class TaskFileModificationListener extends EduDocumentListener { - - public TaskFileModificationListener(TaskFile taskFile) { - super(taskFile); - } - - @Override - protected boolean useLength() { - return false; - } - } - } diff --git a/python/educational/course-creator/src/com/jetbrains/edu/coursecreator/actions/CCAddAnswerPlaceholder.java b/python/educational/course-creator/src/com/jetbrains/edu/coursecreator/actions/CCAddAnswerPlaceholder.java index 6743b25eb374..c7e2dd5f598f 100644 --- a/python/educational/course-creator/src/com/jetbrains/edu/coursecreator/actions/CCAddAnswerPlaceholder.java +++ b/python/educational/course-creator/src/com/jetbrains/edu/coursecreator/actions/CCAddAnswerPlaceholder.java @@ -69,8 +69,6 @@ public class CCAddAnswerPlaceholder extends DumbAwareAction { final PsiDirectory lessonDir = taskDir.getParent(); if (lessonDir == null) return; - final Lesson lesson = service.getLesson(lessonDir.getName()); - final Task task = service.getTask(taskDir.getVirtualFile().getPath()); final TaskFile taskFile = service.getTaskFile(file.getVirtualFile()); if (taskFile == null) { return; diff --git a/python/educational/course-creator/src/com/jetbrains/edu/coursecreator/actions/CCCreateCourseArchive.java b/python/educational/course-creator/src/com/jetbrains/edu/coursecreator/actions/CCCreateCourseArchive.java index ab0a37613690..e710b6932dc5 100644 --- a/python/educational/course-creator/src/com/jetbrains/edu/coursecreator/actions/CCCreateCourseArchive.java +++ b/python/educational/course-creator/src/com/jetbrains/edu/coursecreator/actions/CCCreateCourseArchive.java @@ -29,8 +29,7 @@ import com.jetbrains.edu.coursecreator.ui.CreateCourseArchiveDialog; import org.jetbrains.annotations.NotNull; import java.io.*; -import java.util.Collections; -import java.util.HashMap; +import java.util.AbstractMap; import java.util.Map; import java.util.zip.ZipOutputStream; @@ -76,8 +75,6 @@ public class CCCreateCourseArchive extends DumbAwareAction { } final VirtualFile baseDir = project.getBaseDir(); final Map lessons = service.getLessonsMap(); - //map to store initial task file - final Map taskFiles = new HashMap(); for (Map.Entry task : service.getTasksMap().entrySet()) { final VirtualFile taskDir = LocalFileSystem.getInstance().findFileByPath(task.getKey()); @@ -86,7 +83,9 @@ public class CCCreateCourseArchive extends DumbAwareAction { ApplicationManager.getApplication().runWriteAction(new Runnable() { @Override public void run() { - createUserFile(project, taskFiles, taskDir, taskDir, entry); + TaskFile taskFileCopy = new TaskFile(); + TaskFile.copy(entry.getValue(), taskFileCopy); + createUserFile(project, taskDir, taskDir, new AbstractMap.SimpleEntry(entry.getKey(), taskFileCopy)); } }); } @@ -97,11 +96,11 @@ public class CCCreateCourseArchive extends DumbAwareAction { } public static void createUserFile(@NotNull final Project project, - @NotNull final Map taskFilesCopy, @NotNull final VirtualFile userFileDir, @NotNull final VirtualFile answerFileDir, - @NotNull final Map.Entry taskFiles) { - final String name = taskFiles.getKey(); + @NotNull final Map.Entry taskFileEntry) { + final String name = taskFileEntry.getKey(); + final TaskFile taskFile = taskFileEntry.getValue(); VirtualFile file = userFileDir.findChild(name); if (file != null) { try { @@ -131,12 +130,7 @@ public class CCCreateCourseArchive extends DumbAwareAction { } final Document document = FileDocumentManager.getInstance().getDocument(file); if (document == null) return; - final TaskFile taskFile = taskFiles.getValue(); - TaskFile taskFileSaved = new TaskFile(); - TaskFile.copy(taskFile, taskFileSaved); - for (AnswerPlaceholder answerPlaceholder : taskFile.getAnswerPlaceholders()) { - answerPlaceholder.setLength(answerPlaceholder.getPossibleAnswerLength()); - } + CommandProcessor.getInstance().executeCommand(project, new Runnable() { @Override public void run() { @@ -148,10 +142,9 @@ public class CCCreateCourseArchive extends DumbAwareAction { }); } }, "x", "qwe"); - EduDocumentListener listener = new EduDocumentListener(taskFile); + EduDocumentListener listener = new EduDocumentListener(taskFile, false); document.addDocumentListener(listener); - taskFilesCopy.put(taskFile, taskFileSaved); - Collections.sort(taskFile.getAnswerPlaceholders(), new AnswerPlaceholderComparator()); + taskFile.sortAnswerPlaceholders(); for (int i = taskFile.getAnswerPlaceholders().size() - 1; i >= 0; i--) { final AnswerPlaceholder answerPlaceholder = taskFile.getAnswerPlaceholders().get(i); replaceAnswerPlaceholder(project, document, answerPlaceholder); @@ -181,7 +174,7 @@ public class CCCreateCourseArchive extends DumbAwareAction { ApplicationManager.getApplication().runWriteAction(new Runnable() { @Override public void run() { - document.replaceString(offset, offset + answerPlaceholder.getLength(), taskText); + document.replaceString(offset, offset + answerPlaceholder.getPossibleAnswerLength(), taskText); FileDocumentManager.getInstance().saveDocument(document); } }); diff --git a/python/educational/course-creator/src/com/jetbrains/edu/coursecreator/actions/CCRunTestsAction.java b/python/educational/course-creator/src/com/jetbrains/edu/coursecreator/actions/CCRunTestsAction.java index 6578f48aef79..5a7575882f57 100644 --- a/python/educational/course-creator/src/com/jetbrains/edu/coursecreator/actions/CCRunTestsAction.java +++ b/python/educational/course-creator/src/com/jetbrains/edu/coursecreator/actions/CCRunTestsAction.java @@ -32,7 +32,6 @@ import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiDirectory; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; -import com.intellij.util.containers.HashMap; import com.jetbrains.edu.EduNames; import com.jetbrains.edu.EduUtils; import com.jetbrains.edu.courseFormat.Course; @@ -45,6 +44,7 @@ import com.jetbrains.edu.coursecreator.CCUtils; import org.jetbrains.annotations.NotNull; import java.io.IOException; +import java.util.AbstractMap; import java.util.Map; public abstract class CCRunTestsAction extends AnAction { @@ -234,9 +234,11 @@ public abstract class CCRunTestsAction extends AnAction { Lesson lesson = course.getLessons().get(lessonIndex); if (CCProjectService.indexIsValid(index, lesson.getTaskList())) { Task task = lesson.getTaskList().get(index); - HashMap taskFilesCopy = new HashMap(); for (Map.Entry entry : task.getTaskFiles().entrySet()) { - CCCreateCourseArchive.createUserFile(project, taskFilesCopy, taskResourceDir, taskDir, entry); + TaskFile taskFileCopy = new TaskFile(); + TaskFile.copy(entry.getValue(), taskFileCopy); + CCCreateCourseArchive.createUserFile(project, taskResourceDir, taskDir, + new AbstractMap.SimpleEntry(entry.getKey(), taskFileCopy)); } } } diff --git a/python/educational/course-creator/src/com/jetbrains/edu/coursecreator/actions/CCShowPreview.java b/python/educational/course-creator/src/com/jetbrains/edu/coursecreator/actions/CCShowPreview.java index 3e02774ad20e..f95938961a8b 100644 --- a/python/educational/course-creator/src/com/jetbrains/edu/coursecreator/actions/CCShowPreview.java +++ b/python/educational/course-creator/src/com/jetbrains/edu/coursecreator/actions/CCShowPreview.java @@ -37,7 +37,6 @@ import com.intellij.ui.JBColor; import com.jetbrains.edu.EduAnswerPlaceholderPainter; import com.jetbrains.edu.courseFormat.AnswerPlaceholder; import com.jetbrains.edu.courseFormat.Course; -import com.jetbrains.edu.courseFormat.Task; import com.jetbrains.edu.courseFormat.TaskFile; import com.jetbrains.edu.coursecreator.CCProjectService; import org.jetbrains.annotations.NotNull; @@ -45,9 +44,8 @@ import org.jetbrains.annotations.NotNull; import javax.swing.*; import javax.swing.border.EmptyBorder; import java.text.SimpleDateFormat; +import java.util.AbstractMap; import java.util.Calendar; -import java.util.HashMap; -import java.util.Map; public class CCShowPreview extends DumbAwareAction { private static final Logger LOG = Logger.getInstance(CCShowPreview.class.getName()); @@ -94,22 +92,21 @@ public class CCShowPreview extends DumbAwareAction { if (course == null) { return; } - Task task = service.getTask(taskDir.getVirtualFile().getPath()); TaskFile taskFile = service.getTaskFile(file.getVirtualFile()); if (taskFile == null) { return; } - final Map taskFilesCopy = new HashMap(); - for (final Map.Entry entry : task.getTaskFiles().entrySet()) { - if (entry.getValue() == taskFile) { - ApplicationManager.getApplication().runWriteAction(new Runnable() { - @Override - public void run() { - CCCreateCourseArchive.createUserFile(project, taskFilesCopy, taskDir.getVirtualFile(), taskDir.getVirtualFile(), entry); - } - }); + final TaskFile taskFileCopy = new TaskFile(); + TaskFile.copy(taskFile, taskFileCopy); + final String taskFileName = CCProjectService.getRealTaskFileName(file.getVirtualFile().getName()); + ApplicationManager.getApplication().runWriteAction(new Runnable() { + @Override + public void run() { + CCCreateCourseArchive.createUserFile(project, taskDir.getVirtualFile(), taskDir.getVirtualFile(), + new AbstractMap.SimpleEntry(taskFileName, taskFileCopy)); } - } + }); + String userFileName = CCProjectService.getRealTaskFileName(file.getName()); if (userFileName == null) { return; @@ -133,7 +130,7 @@ public class CCShowPreview extends DumbAwareAction { factory.releaseEditor(createdEditor); } }); - for (AnswerPlaceholder answerPlaceholder : taskFile.getAnswerPlaceholders()) { + for (AnswerPlaceholder answerPlaceholder : taskFileCopy.getAnswerPlaceholders()) { EduAnswerPlaceholderPainter.drawAnswerPlaceholder(createdEditor, answerPlaceholder, true, JBColor.BLUE); } JPanel header = new JPanel(); diff --git a/python/educational/src/com/jetbrains/edu/EduDocumentListener.java b/python/educational/src/com/jetbrains/edu/EduDocumentListener.java index 572b7eb5a0fb..2b142ec2c73d 100644 --- a/python/educational/src/com/jetbrains/edu/EduDocumentListener.java +++ b/python/educational/src/com/jetbrains/edu/EduDocumentListener.java @@ -17,11 +17,27 @@ import java.util.List; */ public class EduDocumentListener extends DocumentAdapter { private final TaskFile myTaskFile; + private final boolean myTrackLength; + private final boolean usePossibleAnswerLength; private final List myAnswerPlaceholders = new ArrayList(); public EduDocumentListener(TaskFile taskFile) { myTaskFile = taskFile; + myTrackLength = true; + usePossibleAnswerLength = false; + } + + public EduDocumentListener(TaskFile taskFile, boolean trackLength) { + myTaskFile = taskFile; + myTrackLength = trackLength; + usePossibleAnswerLength = false; + } + + public EduDocumentListener(TaskFile taskFile, boolean trackLength, boolean usePossibleAnswerLength) { + myTaskFile = taskFile; + myTrackLength = trackLength; + this.usePossibleAnswerLength = usePossibleAnswerLength; } @@ -37,7 +53,7 @@ public class EduDocumentListener extends DocumentAdapter { myAnswerPlaceholders.clear(); for (AnswerPlaceholder answerPlaceholder : myTaskFile.getAnswerPlaceholders()) { int twStart = answerPlaceholder.getRealStartOffset(document); - int length = useLength() ? answerPlaceholder.getLength() : answerPlaceholder.getPossibleAnswerLength(); + int length = usePossibleAnswerLength ? answerPlaceholder.getPossibleAnswerLength() : answerPlaceholder.getLength(); int twEnd = twStart + length; myAnswerPlaceholders.add(new AnswerPlaceholderWrapper(answerPlaceholder, twStart, twEnd)); } @@ -48,6 +64,7 @@ public class EduDocumentListener extends DocumentAdapter { if (!myTaskFile.isTrackChanges()) { return; } + if (myAnswerPlaceholders.isEmpty()) return; if (e instanceof DocumentEventImpl) { DocumentEventImpl event = (DocumentEventImpl)e; Document document = e.getDocument(); @@ -68,19 +85,16 @@ public class EduDocumentListener extends DocumentAdapter { int length = twEnd - twStart; answerPlaceholder.setLine(line); answerPlaceholder.setStart(start); - if (useLength()) { - answerPlaceholder.setLength(length); - } else { + if (usePossibleAnswerLength) { answerPlaceholder.setPossibleAnswer(document.getText(TextRange.create(start, start + length))); } + else if (myTrackLength) { + answerPlaceholder.setLength(length); + } } } } - protected boolean useLength() { - return true; - } - private static class AnswerPlaceholderWrapper { public AnswerPlaceholder myAnswerPlaceholder; public int myTwStart; diff --git a/python/educational/src/com/jetbrains/edu/courseFormat/TaskFile.java b/python/educational/src/com/jetbrains/edu/courseFormat/TaskFile.java index fca8db45311e..36addc3ece22 100644 --- a/python/educational/src/com/jetbrains/edu/courseFormat/TaskFile.java +++ b/python/educational/src/com/jetbrains/edu/courseFormat/TaskFile.java @@ -104,17 +104,18 @@ public class TaskFile { public static void copy(@NotNull final TaskFile source, @NotNull final TaskFile target) { List sourceAnswerPlaceholders = source.getAnswerPlaceholders(); - List windowsCopy = new ArrayList(sourceAnswerPlaceholders.size()); + List answerPlaceholdersCopy = new ArrayList(sourceAnswerPlaceholders.size()); for (AnswerPlaceholder answerPlaceholder : sourceAnswerPlaceholders) { AnswerPlaceholder answerPlaceholderCopy = new AnswerPlaceholder(); answerPlaceholderCopy.setLine(answerPlaceholder.getLine()); answerPlaceholderCopy.setStart(answerPlaceholder.getStart()); + answerPlaceholderCopy.setTaskText(answerPlaceholder.getTaskText()); answerPlaceholderCopy.setLength(answerPlaceholder.getLength()); answerPlaceholderCopy.setPossibleAnswer(answerPlaceholder.getPossibleAnswer()); answerPlaceholderCopy.setIndex(answerPlaceholder.getIndex()); - windowsCopy.add(answerPlaceholderCopy); + answerPlaceholdersCopy.add(answerPlaceholderCopy); } - target.setAnswerPlaceholders(windowsCopy); + target.setAnswerPlaceholders(answerPlaceholdersCopy); } public void setUserCreated(boolean userCreated) {