reused course format in course creator plugin

//TODO: answer placeholders sort
extract painter
This commit is contained in:
Ekaterina Tuzova
2015-02-14 17:29:44 +03:00
parent dbba86379f
commit 796947568b
36 changed files with 477 additions and 411 deletions
@@ -5,10 +5,12 @@
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/resources" type="java-resource" />
<excludeFolder url="file://$MODULE_DIR$/src/com/jetbrains/edu/coursecreator/format" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="gson" level="project" />
<orderEntry type="module" module-name="lang-impl" />
<orderEntry type="module" module-name="educational" />
</component>
</module>
@@ -55,7 +55,7 @@
<action id="CreateTaskFile" class="com.jetbrains.edu.coursecreator.actions.CCCreateTaskFile">
<add-to-group group-id="NewGroup" anchor="before" relative-to-action="NewFile"/>
</action>
<action id="AddTaskWindow" class="com.jetbrains.edu.coursecreator.actions.CCAddTaskWindow">
<action id="AddTaskWindow" class="com.jetbrains.edu.coursecreator.actions.CCAddAnswerPlaceholder">
<add-to-group group-id="EditorPopupMenu" anchor="before" relative-to-action="CopyReference"/>
</action>
<action id="ShowTaskWindowDetails" class="com.jetbrains.edu.coursecreator.actions.CCShowTaskWindowDetails">
@@ -0,0 +1,174 @@
package com.jetbrains.edu.coursecreator;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.RangeMarker;
import com.intellij.openapi.editor.colors.EditorColorsManager;
import com.intellij.openapi.editor.colors.EditorColorsScheme;
import com.intellij.openapi.editor.impl.DocumentImpl;
import com.intellij.openapi.editor.markup.*;
import com.intellij.openapi.project.Project;
import com.intellij.ui.JBColor;
import com.jetbrains.edu.courseFormat.AnswerPlaceholder;
import com.jetbrains.edu.courseFormat.TaskFile;
import org.jetbrains.annotations.NotNull;
import java.awt.*;
import java.util.List;
public class CCAnswerPlaceholderPainter {
private CCAnswerPlaceholderPainter() {
}
public static void drawHighlighter(@NotNull final AnswerPlaceholder placeholder, @NotNull final Editor editor, boolean useLength) {
drawAnswerPlaceholder(editor, placeholder, useLength, JBColor.BLUE);
//int startOffset = placeholder.getRealStartOffset(editor.getDocument());
//final int length = placeholder.getLength();
//final int replacementLength = placeholder.getPossibleAnswer().length();
//int highlighterLength = useLength ? length : replacementLength;
//int endOffset = startOffset + highlighterLength;
//TextAttributes defaultTestAttributes =
// EditorColorsManager.getInstance().getGlobalScheme().getAttributes(EditorColors.LIVE_TEMPLATE_ATTRIBUTES);
//defaultTestAttributes.setEffectColor(JBColor.BLUE);
//RangeHighlighter highlighter =
// editor.getMarkupModel().addRangeHighlighter(startOffset, endOffset, HighlighterLayer.LAST + 1, defaultTestAttributes,
// HighlighterTargetArea.EXACT_RANGE);
//highlighter.setGreedyToLeft(true);
//highlighter.setGreedyToRight(true);
}
public static void drawAnswerPlaceholder(@NotNull final Editor editor, @NotNull final AnswerPlaceholder placeholder, boolean useLength,
@NotNull final JBColor color) {
Document document = editor.getDocument();
if (useLength && !placeholder.isValid(document)) {
return;
}
EditorColorsScheme scheme = EditorColorsManager.getInstance().getGlobalScheme();
final TextAttributes defaultTestAttributes = new TextAttributes(scheme.getDefaultForeground(), scheme.getDefaultBackground(), null,
EffectType.BOXED, Font.PLAIN);
final Project project = editor.getProject();
assert project != null;
int startOffset = placeholder.getRealStartOffset(document);
final int length = placeholder.getLength();
final int replacementLength = placeholder.getPossibleAnswerLength();
int highlighterLength = useLength ? length : replacementLength;
int endOffset = startOffset + highlighterLength;
RangeHighlighter
highlighter = editor.getMarkupModel().addRangeHighlighter(startOffset, endOffset, HighlighterLayer.LAST + 1,
defaultTestAttributes, HighlighterTargetArea.EXACT_RANGE);
highlighter.setCustomRenderer(new CustomHighlighterRenderer() {
@Override
public void paint(@NotNull Editor editor, @NotNull RangeHighlighter highlighter, @NotNull Graphics g) {
g.setColor(color);
Point point = editor.logicalPositionToXY(editor.offsetToLogicalPosition(highlighter.getStartOffset()));
Point pointEnd = editor.logicalPositionToXY(editor.offsetToLogicalPosition(highlighter.getEndOffset()));
g.drawRect(point.x, point.y - 2, (pointEnd.x - point.x), editor.getLineHeight() + 1);
}
});
editor.getCaretModel().moveToOffset(startOffset);
highlighter.setGreedyToLeft(true);
highlighter.setGreedyToRight(true);
}
/*
public static void drawAnswerPlaceholder(@NotNull final Editor editor, AnswerPlaceholder answerPlaceholder) {
Document document = editor.getDocument();
if (!answerPlaceholder.isValid(document)) {
return;
}
EditorColorsScheme scheme = EditorColorsManager.getInstance().getGlobalScheme();
final TextAttributes defaultTestAttributes = new TextAttributes(scheme.getDefaultForeground(), scheme.getDefaultBackground(), null,
EffectType.BOXED, Font.PLAIN);
final Project project = editor.getProject();
assert project != null;
final JBColor color = StudyTaskManager.getInstance(project).getColor(answerPlaceholder);
int startOffset = answerPlaceholder.getRealStartOffset(document);
RangeHighlighter
highlighter = editor.getMarkupModel().addRangeHighlighter(startOffset, startOffset + answerPlaceholder.getLength(), HighlighterLayer.LAST + 1,
defaultTestAttributes, HighlighterTargetArea.EXACT_RANGE);
highlighter.setCustomRenderer(new CustomHighlighterRenderer() {
@Override
public void paint(@NotNull Editor editor, @NotNull RangeHighlighter highlighter, @NotNull Graphics g) {
g.setColor(color);
Point point = editor.logicalPositionToXY(editor.offsetToLogicalPosition(highlighter.getStartOffset()));
Point pointEnd = editor.logicalPositionToXY(editor.offsetToLogicalPosition(highlighter.getEndOffset()));
g.drawRect(point.x, point.y - 2, (pointEnd.x - point.x), editor.getLineHeight() + 1);
}
});
editor.getCaretModel().moveToOffset(startOffset);
highlighter.setGreedyToLeft(true);
highlighter.setGreedyToRight(true);
}
/*
public static void drawAllWindows(Editor editor, TaskFile taskFile) {
editor.getMarkupModel().removeAllHighlighters();
for (AnswerPlaceholder answerPlaceholder : taskFile.getAnswerPlaceholders()) {
drawAnswerPlaceholder(editor, answerPlaceholder);
}
final Document document = editor.getDocument();
EditorActionManager.getInstance()
.setReadonlyFragmentModificationHandler(document, new TaskWindowDeleteHandler(editor));
createGuardedBlocks(editor, taskFile);
editor.getColorsScheme().setColor(EditorColors.READONLY_FRAGMENT_BACKGROUND_COLOR, null);
}
*//**
* Marks symbols adjacent to task windows as read-only fragments
*//*
public static void createGuardedBlocks(@NotNull final Editor editor, TaskFile taskFile) {
final Document document = editor.getDocument();
if (document instanceof DocumentImpl) {
DocumentImpl documentImpl = (DocumentImpl)document;
List<RangeMarker> blocks = documentImpl.getGuardedBlocks();
for (AnswerPlaceholder answerPlaceholder : taskFile.getAnswerPlaceholders()) {
if (!answerPlaceholder.isValid(document)) {
return;
}
int start = answerPlaceholder.getRealStartOffset(document);
int end = start + answerPlaceholder.getLength();
if (start != 0) {
createGuardedBlock(editor, blocks, start - 1, start);
}
if (end != document.getTextLength()) {
createGuardedBlock(editor, blocks, end, end + 1);
}
}
}
}
*/
public static void createGuardedBlock(Editor editor, List<RangeMarker> blocks, int start, int end) {
RangeHighlighter rh = editor.getMarkupModel()
.addRangeHighlighter(start, end, HighlighterLayer.LAST + 1, null, HighlighterTargetArea.EXACT_RANGE);
blocks.add(rh);
}
public static void createGuardedBlocks(@NotNull final Editor editor, TaskFile taskFile) {
for (AnswerPlaceholder answerPlaceholder : taskFile.getAnswerPlaceholders()) {
createGuardedBlocks(editor, answerPlaceholder);
}
}
public static void createGuardedBlocks(@NotNull final Editor editor, AnswerPlaceholder placeholder) {
Document document = editor.getDocument();
if (document instanceof DocumentImpl) {
DocumentImpl documentImpl = (DocumentImpl)document;
java.util.List<RangeMarker> blocks = documentImpl.getGuardedBlocks();
int start = placeholder.getRealStartOffset(document);
int end = start + placeholder.getPossibleAnswer().length();
if (start != 0) {
createGuardedBlock(editor, blocks, start - 1, start);
}
if (end != document.getTextLength()) {
createGuardedBlock(editor, blocks, end, end + 1);
}
}
}
}
@@ -4,8 +4,9 @@ import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.event.DocumentAdapter;
import com.intellij.openapi.editor.event.DocumentEvent;
import com.intellij.openapi.editor.impl.event.DocumentEventImpl;
import com.jetbrains.edu.coursecreator.format.AnswerPlaceholder;
import com.jetbrains.edu.coursecreator.format.TaskFile;
import com.intellij.openapi.util.TextRange;
import com.jetbrains.edu.courseFormat.AnswerPlaceholder;
import com.jetbrains.edu.courseFormat.TaskFile;
import java.util.ArrayList;
import java.util.List;
@@ -32,7 +33,7 @@ public abstract class CCDocumentListener extends DocumentAdapter {
myTaskWindows.clear();
for (AnswerPlaceholder answerPlaceholder : myTaskFile.getAnswerPlaceholders()) {
int twStart = answerPlaceholder.getRealStartOffset(document);
int length = useLength() ? answerPlaceholder.getLength() : answerPlaceholder.getReplacementLength();
int length = useLength() ? answerPlaceholder.getLength() : answerPlaceholder.getPossibleAnswerLength();
int twEnd = twStart + length;
myTaskWindows.add(new TaskWindowWrapper(answerPlaceholder, twStart, twEnd));
}
@@ -63,7 +64,7 @@ public abstract class CCDocumentListener extends DocumentAdapter {
if (useLength()) {
answerPlaceholder.setLength(length);
} else {
answerPlaceholder.setReplacementLength(length);
answerPlaceholder.setPossibleAnswer(document.getText(TextRange.create(start, start + length )));
}
}
}
@@ -12,10 +12,8 @@ import com.intellij.openapi.editor.event.EditorFactoryListener;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.jetbrains.edu.coursecreator.format.Course;
import com.jetbrains.edu.coursecreator.format.Lesson;
import com.jetbrains.edu.coursecreator.format.Task;
import com.jetbrains.edu.coursecreator.format.TaskFile;
import com.jetbrains.edu.courseFormat.Course;
import com.jetbrains.edu.courseFormat.TaskFile;
import org.jetbrains.annotations.NotNull;
public class CCEditorFactoryListener implements EditorFactoryListener {
@@ -30,7 +28,8 @@ public class CCEditorFactoryListener implements EditorFactoryListener {
if (virtualFile == null) {
return;
}
Course course = CCProjectService.getInstance(project).getCourse();
final CCProjectService service = CCProjectService.getInstance(project);
Course course = service.getCourse();
if (course == null) {
return;
}
@@ -40,9 +39,7 @@ public class CCEditorFactoryListener implements EditorFactoryListener {
}
final VirtualFile lessonDir = taskDir.getParent();
if (lessonDir == null) return;
final Lesson lesson = course.getLesson(lessonDir.getName());
final Task task = lesson.getTask(taskDir.getName());
final TaskFile taskFile = task.getTaskFile(virtualFile.getName());
final TaskFile taskFile = service.getTaskFile(virtualFile);
if (taskFile == null) {
return;
}
@@ -51,9 +48,9 @@ public class CCEditorFactoryListener implements EditorFactoryListener {
editor.getDocument().addDocumentListener(listener);
EditorActionManager.getInstance()
.setReadonlyFragmentModificationHandler(editor.getDocument(), new TaskWindowDeleteHandler(editor));
CCProjectService.getInstance(project).drawTaskWindows(virtualFile, editor);
service.drawTaskWindows(virtualFile, editor);
editor.getColorsScheme().setColor(EditorColors.READONLY_FRAGMENT_BACKGROUND_COLOR, null);
taskFile.createGuardedBlocks(editor);
CCAnswerPlaceholderPainter.createGuardedBlocks(editor, taskFile);
}
@Override
@@ -16,11 +16,11 @@ import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileAdapter;
import com.intellij.openapi.vfs.VirtualFileEvent;
import com.intellij.openapi.vfs.VirtualFileManager;
import com.jetbrains.edu.courseFormat.Course;
import com.jetbrains.edu.courseFormat.Lesson;
import com.jetbrains.edu.courseFormat.Task;
import com.jetbrains.edu.courseFormat.TaskFile;
import com.jetbrains.edu.coursecreator.actions.CCRunTestsAction;
import com.jetbrains.edu.coursecreator.format.Course;
import com.jetbrains.edu.coursecreator.format.Lesson;
import com.jetbrains.edu.coursecreator.format.Task;
import com.jetbrains.edu.coursecreator.format.TaskFile;
import org.jetbrains.annotations.NotNull;
import java.io.IOException;
@@ -115,10 +115,10 @@ public class CCProjectComponent implements ProjectComponent {
}
VirtualFile removedFile = event.getFile();
if (removedFile.getName().contains(".answer")) {
deleteTaskFile(course, removedFile);
deleteTaskFile(removedFile);
}
if (removedFile.getName().contains("task")) {
deleteTask(course, removedFile);
deleteTask(removedFile);
}
if (removedFile.getName().contains("lesson")) {
deleteLesson(course, removedFile);
@@ -130,15 +130,17 @@ public class CCProjectComponent implements ProjectComponent {
if (!courseDir.getName().equals(myProject.getName())) {
return;
}
Lesson lesson = course.getLesson(file.getName());
final CCProjectService projectService = CCProjectService.getInstance(myProject);
Lesson lesson = projectService.getLesson(file.getName());
if (lesson != null) {
course.getLessons().remove(lesson);
course.getLessonsMap().remove(file.getName());
projectService.getLessonsMap().remove(file.getName());
}
}
private void deleteTask(Course course, VirtualFile removedFile) {
private void deleteTask(VirtualFile removedFile) {
VirtualFile lessonDir = removedFile.getParent();
final CCProjectService projectService = CCProjectService.getInstance(myProject);
if (lessonDir == null || !lessonDir.getName().contains("lesson")) {
return;
}
@@ -146,20 +148,20 @@ public class CCProjectComponent implements ProjectComponent {
if (!courseDir.getName().equals(myProject.getName())) {
return;
}
Lesson lesson = course.getLesson(lessonDir.getName());
Lesson lesson = projectService.getLesson(lessonDir.getName());
if (lesson == null) {
return;
}
Task task = lesson.getTask(removedFile.getName());
Task task = projectService.getTask(removedFile.getPath());
if (task == null) {
return;
}
lesson.getTaskList().remove(task);
lesson.getTasksMap().remove(removedFile.getName());
projectService.getTasksMap().remove(removedFile.getPath());
}
private void deleteTaskFile(Course course, VirtualFile removedFile) {
private void deleteTaskFile(VirtualFile removedFile) {
final CCProjectService projectService = CCProjectService.getInstance(myProject);
final VirtualFile taskDir = removedFile.getParent();
if (taskDir == null || !taskDir.getName().contains("task")) {
return;
@@ -172,15 +174,15 @@ public class CCProjectComponent implements ProjectComponent {
if (!courseDir.getName().equals(myProject.getName())) {
return;
}
Lesson lesson = course.getLesson(lessonDir.getName());
Lesson lesson = projectService.getLesson(lessonDir.getName());
if (lesson == null) {
return;
}
Task task = lesson.getTask(taskDir.getName());
Task task = projectService.getTask(taskDir.getPath());
if (task == null) {
return;
}
TaskFile taskFile = task.getTaskFile(removedFile.getName());
TaskFile taskFile = projectService.getTaskFile(removedFile);
if (taskFile == null) {
return;
}
@@ -29,9 +29,9 @@ import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.io.FileUtilRt;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.util.xmlb.XmlSerializer;
import com.jetbrains.edu.coursecreator.format.*;
import org.jdom.Element;
import com.intellij.psi.PsiDirectory;
import com.intellij.util.xmlb.XmlSerializerUtil;
import com.jetbrains.edu.courseFormat.*;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -46,44 +46,51 @@ import java.util.Map;
@Storage(file = "$PROJECT_CONFIG_DIR$/course_service.xml")
}
)
public class CCProjectService implements PersistentStateComponent<Element> {
public class CCProjectService implements PersistentStateComponent<CCProjectService> {
private static final Logger LOG = Logger.getInstance(CCProjectService.class.getName());
private Course myCourse;
public static final String COURSE_ELEMENT = "course";
//directory name to Lesson
private Map<String, Lesson> myLessonsMap = new HashMap<String, Lesson>();
//directory path to Task
public Map<String, Task> myTasksMap = new HashMap<String, Task>();
private static final Map<Document, CCDocumentListener> myDocumentListeners = new HashMap<Document, CCDocumentListener>();
public void setCourse(@NotNull final Course course) {
myCourse = course;
public Map<String, Lesson> getLessonsMap() {
return myLessonsMap;
}
public Course getCourse() {
return myCourse;
public void setLessonsMap(Map<String, Lesson> lessonsMap) {
myLessonsMap = lessonsMap;
}
@Override
public Element getState() {
final Element el = new Element("CCProjectService");
if (myCourse != null) {
Element courseElement = new Element(COURSE_ELEMENT);
XmlSerializer.serializeInto(myCourse, courseElement);
el.addContent(courseElement);
}
return el;
public Lesson getLesson(@NotNull final String name) {
return myLessonsMap.get(name);
}
@Override
public void loadState(Element el) {
myCourse = XmlSerializer.deserialize(el.getChild(COURSE_ELEMENT), Course.class);
if (myCourse != null) {
myCourse.init();
}
public void addLesson(@NotNull final Lesson lesson, @NotNull final PsiDirectory directory) {
myLessonsMap.put(directory.getName(), lesson);
}
public static CCProjectService getInstance(@NotNull Project project) {
return ServiceManager.getService(project, CCProjectService.class);
public Map<String, Task> getTasksMap() {
return myTasksMap;
}
public void setTasksMap(Map<String, Task> tasksMap) {
myTasksMap = tasksMap;
}
public void addTask(@NotNull final Task task, PsiDirectory taskDirectory) {
myTasksMap.put(taskDirectory.getVirtualFile().getPath(), task);
}
public Task getTask(@NotNull final String name) {
return myTasksMap.get(name);
}
public static void deleteProjectFile(File file, @NotNull final Project project) {
if (!file.delete()) {
LOG.info("Failed to delete file " + file.getPath());
@@ -110,15 +117,16 @@ public class CCProjectService implements PersistentStateComponent<Element> {
if (!lessonDirName.contains("lesson")) {
return null;
}
Lesson lesson = myCourse.getLessonsMap().get(lessonDirName);
Lesson lesson = myLessonsMap.get(lessonDirName);
if (lesson == null) {
return null;
}
Task task = lesson.getTask(taskDirName);
Task task = getTask(taskDir.getPath());
if (task == null) {
return null;
}
return task.getTaskFile(virtualFile.getName());
String fileName = getRealTaskFileName(virtualFile.getName());
return task.getTaskFile(fileName);
}
public void drawTaskWindows(@NotNull final VirtualFile virtualFile, @NotNull final Editor editor) {
@@ -128,7 +136,7 @@ public class CCProjectService implements PersistentStateComponent<Element> {
}
List<AnswerPlaceholder> answerPlaceholders = taskFile.getAnswerPlaceholders();
for (AnswerPlaceholder answerPlaceholder : answerPlaceholders) {
answerPlaceholder.drawHighlighter(editor, false);
CCAnswerPlaceholderPainter.drawHighlighter(answerPlaceholder, editor, false);
}
}
@@ -185,6 +193,8 @@ public class CCProjectService implements PersistentStateComponent<Element> {
}
return Integer.parseInt(fullName.substring(logicalName.length())) - 1;
}
@Nullable
public static String getRealTaskFileName(String name) {
String nameWithoutExtension = FileUtil.getNameWithoutExtension(name);
String extension = FileUtilRt.getExtension(name);
@@ -207,4 +217,27 @@ public class CCProjectService implements PersistentStateComponent<Element> {
CCUtils.enableAction(e, true);
return true;
}
public Course getCourse() {
return myCourse;
}
public void setCourse(@NotNull final Course course) {
myCourse = course;
}
@Override
public CCProjectService getState() {
return this;
}
@Override
public void loadState(CCProjectService state) {
XmlSerializerUtil.copyBean(state, this);
}
public static CCProjectService getInstance(@NotNull Project project) {
return ServiceManager.getService(project, CCProjectService.class);
}
}
@@ -22,11 +22,11 @@ import com.intellij.psi.PsiFile;
import com.intellij.refactoring.listeners.RefactoringElementAdapter;
import com.intellij.refactoring.listeners.RefactoringElementListener;
import com.intellij.refactoring.listeners.RefactoringElementListenerProvider;
import com.jetbrains.edu.courseFormat.Course;
import com.jetbrains.edu.courseFormat.Lesson;
import com.jetbrains.edu.courseFormat.Task;
import com.jetbrains.edu.courseFormat.TaskFile;
import com.jetbrains.edu.coursecreator.actions.CCRunTestsAction;
import com.jetbrains.edu.coursecreator.format.Course;
import com.jetbrains.edu.coursecreator.format.Lesson;
import com.jetbrains.edu.coursecreator.format.Task;
import com.jetbrains.edu.coursecreator.format.TaskFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -64,7 +64,8 @@ public class CCRefactoringElementListenerProvider implements RefactoringElementL
private static void renameTaskFile(PsiFile file, String oldName) {
final PsiDirectory taskDir = file.getContainingDirectory();
Course course = CCProjectService.getInstance(file.getProject()).getCourse();
final CCProjectService service = CCProjectService.getInstance(file.getProject());
Course course = service.getCourse();
if (course == null) {
return;
}
@@ -75,11 +76,11 @@ public class CCRefactoringElementListenerProvider implements RefactoringElementL
if (lessonDir == null || !lessonDir.getName().contains("lesson")) {
return;
}
Lesson lesson = course.getLesson(lessonDir.getName());
Lesson lesson = service.getLesson(lessonDir.getName());
if (lesson == null) {
return;
}
Task task = lesson.getTask(taskDir.getName());
Task task = service.getTask(taskDir.getVirtualFile().getPath());
if (task == null) {
return;
}
@@ -13,7 +13,7 @@ import com.intellij.openapi.roots.ContentEntry;
import com.intellij.openapi.roots.ModifiableRootModel;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.vfs.VirtualFile;
import com.jetbrains.edu.coursecreator.format.Course;
import com.jetbrains.edu.courseFormat.Course;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -13,17 +13,21 @@ import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.psi.PsiDirectory;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiFile;
import com.jetbrains.edu.courseFormat.AnswerPlaceholder;
import com.jetbrains.edu.courseFormat.Lesson;
import com.jetbrains.edu.courseFormat.Task;
import com.jetbrains.edu.courseFormat.TaskFile;
import com.jetbrains.edu.coursecreator.CCAnswerPlaceholderPainter;
import com.jetbrains.edu.coursecreator.CCProjectService;
import com.jetbrains.edu.coursecreator.format.*;
import com.jetbrains.edu.coursecreator.ui.CreateTaskWindowDialog;
import org.jetbrains.annotations.NotNull;
import java.util.List;
public class CCAddTaskWindow extends DumbAwareAction {
private static final Logger LOG = Logger.getInstance(CCAddTaskWindow.class);
public class CCAddAnswerPlaceholder extends DumbAwareAction {
private static final Logger LOG = Logger.getInstance(CCAddAnswerPlaceholder.class);
public CCAddTaskWindow() {
public CCAddAnswerPlaceholder() {
super("Add Answer Placeholder", "Add answer placeholder", null);
}
@@ -32,7 +36,7 @@ public class CCAddTaskWindow extends DumbAwareAction {
List<AnswerPlaceholder> answerPlaceholders = taskFile.getAnswerPlaceholders();
for (AnswerPlaceholder existingAnswerPlaceholder : answerPlaceholders) {
int twStart = existingAnswerPlaceholder.getRealStartOffset(document);
int twEnd = existingAnswerPlaceholder.getReplacementLength() + twStart;
int twEnd = existingAnswerPlaceholder.getPossibleAnswerLength() + twStart;
if ((start >= twStart && start < twEnd) || (end > twStart && end <= twEnd) ||
(twStart >= start && twStart < end) || (twEnd > start && twEnd <= end)) {
return true;
@@ -57,25 +61,27 @@ public class CCAddTaskWindow extends DumbAwareAction {
final int start = model.getSelectionStart();
final int end = model.getSelectionEnd();
final int lineNumber = document.getLineNumber(start);
final int length = end - start;
int realStart = start - document.getLineStartOffset(lineNumber);
final CCProjectService service = CCProjectService.getInstance(project);
final Course course = service.getCourse();
final PsiDirectory taskDir = file.getContainingDirectory();
final PsiDirectory lessonDir = taskDir.getParent();
if (lessonDir == null) return;
final Lesson lesson = course.getLesson(lessonDir.getName());
final Task task = lesson.getTask(taskDir.getName());
final TaskFile taskFile = task.getTaskFile(file.getName());
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;
}
if (areTaskWindowsIntersect(taskFile, document, start, end)) {
return;
}
final AnswerPlaceholder answerPlaceholder = new AnswerPlaceholder(lineNumber, realStart, length, model.getSelectedText());
final AnswerPlaceholder answerPlaceholder = new AnswerPlaceholder();
answerPlaceholder.setLine(lineNumber);
answerPlaceholder.setStart(realStart);
answerPlaceholder.setPossibleAnswer(model.getSelectedText());
CreateTaskWindowDialog dlg = new CreateTaskWindowDialog(project, answerPlaceholder, lesson.getIndex(),
task.getIndex(), file.getVirtualFile().getNameWithoutExtension(),
taskFile.getAnswerPlaceholders().size() + 1);
@@ -84,10 +90,11 @@ public class CCAddTaskWindow extends DumbAwareAction {
return;
}
int index = taskFile.getAnswerPlaceholders().size() + 1;
taskFile.addTaskWindow(answerPlaceholder, index);
taskFile.sortTaskWindows();
answerPlaceholder.drawHighlighter(editor, false);
answerPlaceholder.createGuardedBlocks(editor);
answerPlaceholder.setIndex(index);
taskFile.addAnswerPlaceholder(answerPlaceholder);
//taskFile.sortTaskWindows();
CCAnswerPlaceholderPainter.drawHighlighter(answerPlaceholder, editor, false);
CCAnswerPlaceholderPainter.createGuardedBlocks(editor, answerPlaceholder);
}
@Override
@@ -119,24 +126,23 @@ public class CCAddTaskWindow extends DumbAwareAction {
int end = selectionModel.getSelectionEnd();
final CCProjectService service = CCProjectService.getInstance(project);
final Course course = service.getCourse();
final PsiDirectory taskDir = file.getContainingDirectory();
final PsiDirectory lessonDir = taskDir.getParent();
if (lessonDir == null) return;
final Lesson lesson = course.getLesson(lessonDir.getName());
final Lesson lesson = service.getLesson(lessonDir.getName());
if (lesson == null) {
presentation.setVisible(false);
presentation.setEnabled(false);
return;
}
final Task task = lesson.getTask(taskDir.getName());
final Task task = service.getTask(taskDir.getVirtualFile().getPath());
if (task == null) {
presentation.setVisible(false);
presentation.setEnabled(false);
return;
}
TaskFile taskFile = task.getTaskFile(file.getName());
TaskFile taskFile = service.getTaskFile(file.getVirtualFile());
if (taskFile == null) {
LOG.info("could not find task file");
presentation.setVisible(false);
@@ -11,8 +11,8 @@ import com.intellij.openapi.project.DumbAwareAction;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.psi.PsiDirectory;
import com.jetbrains.edu.courseFormat.Course;
import com.jetbrains.edu.coursecreator.CCProjectService;
import com.jetbrains.edu.coursecreator.format.Course;
import com.jetbrains.edu.coursecreator.ui.CCNewProjectPanel;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -16,19 +16,19 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.util.io.ZipUtil;
import com.jetbrains.edu.courseFormat.*;
import com.jetbrains.edu.coursecreator.CCDocumentListener;
import com.jetbrains.edu.coursecreator.CCLanguageManager;
import com.jetbrains.edu.coursecreator.CCProjectService;
import com.jetbrains.edu.coursecreator.CCUtils;
import com.jetbrains.edu.coursecreator.CCLanguageManager;
import com.jetbrains.edu.coursecreator.format.*;
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.Map;
import java.util.zip.ZipOutputStream;
@@ -74,28 +74,24 @@ public class CCCreateCourseArchive extends DumbAwareAction {
return;
}
final VirtualFile baseDir = project.getBaseDir();
final Map<String, Lesson> lessons = course.getLessonsMap();
final Map<String, Lesson> lessons = service.getLessonsMap();
//map to store initial task file
final Map<TaskFile, TaskFile> taskFiles = new HashMap<TaskFile, TaskFile>();
for (Map.Entry<String, Lesson> lesson : lessons.entrySet()) {
final VirtualFile lessonDir = baseDir.findChild(lesson.getKey());
if (lessonDir == null) continue;
for (Map.Entry<String, Task> task : lesson.getValue().myTasksMap.entrySet()) {
final VirtualFile taskDir = lessonDir.findChild(task.getKey());
if (taskDir == null) continue;
for (final Map.Entry<String, TaskFile> entry : task.getValue().task_files.entrySet()) {
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
public void run() {
createUserFile(project, taskFiles, taskDir, taskDir, entry);
}
});
}
for (Map.Entry<String, Task> task : service.getTasksMap().entrySet()) {
final VirtualFile taskDir = LocalFileSystem.getInstance().findFileByPath(task.getKey());
if (taskDir == null) continue;
for (final Map.Entry<String, TaskFile> entry : task.getValue().getTaskFiles().entrySet()) {
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
public void run() {
createUserFile(project, taskFiles, taskDir, taskDir, entry);
}
});
}
}
generateJson(project);
packCourse(baseDir, lessons, course);
resetTaskFiles(taskFiles);
synchronize(project);
}
@@ -136,9 +132,9 @@ public class CCCreateCourseArchive extends DumbAwareAction {
if (document == null) return;
final TaskFile taskFile = taskFiles.getValue();
TaskFile taskFileSaved = new TaskFile();
taskFile.copy(taskFileSaved);
TaskFile.copy(taskFile, taskFileSaved);
for (AnswerPlaceholder answerPlaceholder : taskFile.getAnswerPlaceholders()) {
answerPlaceholder.setLength(answerPlaceholder.getReplacementLength());
answerPlaceholder.setLength(answerPlaceholder.getPossibleAnswerLength());
}
CommandProcessor.getInstance().executeCommand(project, new Runnable() {
@Override
@@ -154,7 +150,7 @@ public class CCCreateCourseArchive extends DumbAwareAction {
InsertionListener listener = new InsertionListener(taskFile);
document.addDocumentListener(listener);
taskFilesCopy.put(taskFile, taskFileSaved);
Collections.sort(taskFile.getAnswerPlaceholders());
//Collections.sort(taskFile.getAnswerPlaceholders());
for (int i = taskFile.getAnswerPlaceholders().size() - 1; i >= 0; i--) {
final AnswerPlaceholder answerPlaceholder = taskFile.getAnswerPlaceholders().get(i);
replaceTaskWindow(project, document, answerPlaceholder);
@@ -198,14 +194,6 @@ public class CCCreateCourseArchive extends DumbAwareAction {
ProjectView.getInstance(project).refresh();
}
public static void resetTaskFiles(@NotNull final Map<TaskFile, TaskFile> taskFiles) {
for (Map.Entry<TaskFile, TaskFile> entry : taskFiles.entrySet()) {
TaskFile realTaskFile = entry.getKey();
TaskFile savedTaskFile = entry.getValue();
realTaskFile.update(savedTaskFile);
}
}
private void packCourse(@NotNull final VirtualFile baseDir, @NotNull final Map<String, Lesson> lessons, @NotNull final Course course) {
try {
File zipFile = new File(myLocationDir, myZipName + ".zip");
@@ -13,11 +13,12 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiDirectory;
import com.intellij.psi.PsiManager;
import com.intellij.util.PlatformIcons;
import com.jetbrains.edu.courseFormat.Course;
import com.jetbrains.edu.courseFormat.Lesson;
import com.jetbrains.edu.coursecreator.CCProjectService;
import com.jetbrains.edu.coursecreator.CCUtils;
import com.jetbrains.edu.coursecreator.format.Course;
import com.jetbrains.edu.coursecreator.format.Lesson;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -49,11 +50,11 @@ public class CCCreateLesson extends DumbAwareAction {
//"Create Lesson" invoked from project root creates new lesson as last lesson
if (directory.getVirtualFile().equals(project.getBaseDir())) {
final int size = course.getLessons().size();
createLesson(directory, size + 1, view, course);
createLesson(project, size + 1, view, course);
return;
}
//"Create Lesson" invoked from any of lesson directories creates new lesson as next lesson
Lesson lesson = course.getLesson(directory.getName());
Lesson lesson = service.getLesson(directory.getName());
if (lesson != null) {
int index = lesson.getIndex();
List<Lesson> lessons = course.getLessons();
@@ -65,12 +66,11 @@ public class CCCreateLesson extends DumbAwareAction {
if (parent == null) {
return;
}
createLesson(parent, index + 1, view, course);
course.init();
createLesson(project, index + 1, view, course);
}
}
private static void createLesson(@NotNull final PsiDirectory projectDir,
private static void createLesson(@NotNull final Project project,
final int index,
final IdeView view,
@NotNull final Course course) {
@@ -81,7 +81,7 @@ public class CCCreateLesson extends DumbAwareAction {
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
public void run() {
createLessonDir(projectDir, index, lessonName, view, course);
createLessonDir(project, index, lessonName, view, course);
}
});
}
@@ -91,7 +91,8 @@ public class CCCreateLesson extends DumbAwareAction {
if (lessonDir == null) {
return;
}
Lesson l = course.getLesson(lessonDir.getName());
final CCProjectService service = CCProjectService.getInstance(project);
Lesson l = service.getLesson(lessonDir.getName());
if (l == null) {
return;
}
@@ -108,21 +109,24 @@ public class CCCreateLesson extends DumbAwareAction {
}
}
});
course.getLessonsMap().put(lessonDir.getName(), l);
service.getLessonsMap().put(lessonDir.getName(), l);
}
@Nullable
public static PsiDirectory createLessonDir(@NotNull final PsiDirectory projectDir, int index, String name, final IdeView view,
public static PsiDirectory createLessonDir(@NotNull final Project project, int index, String name, final IdeView view,
@NotNull final Course course) {
String lessonFolderName = "lesson" + index;
final PsiDirectory projectDir = PsiManager.getInstance(project).findDirectory(project.getBaseDir());
final PsiDirectory lessonDirectory = DirectoryUtil.createSubdirectories("lesson" + index, projectDir, "\\/");
final CCProjectService service = CCProjectService.getInstance(project);
if (lessonDirectory != null) {
if (view != null) {
view.selectElement(lessonDirectory);
}
final Lesson lesson = new Lesson(name != null ? name : lessonFolderName);
final Lesson lesson = new Lesson();
lesson.setName(name != null ? name : lessonFolderName);
lesson.setIndex(index);
course.addLesson(lesson, lessonDirectory);
service.addLesson(lesson, lessonDirectory);
}
return lessonDirectory;
}
@@ -148,8 +152,9 @@ public class CCCreateLesson extends DumbAwareAction {
CCUtils.enableAction(event, true);
return;
}
Course course = CCProjectService.getInstance(project).getCourse();
if (directory != null && course != null && course.getLesson(directory.getName()) != null) {
final CCProjectService service = CCProjectService.getInstance(project);
Course course = service.getCourse();
if (directory != null && course != null && service.getLesson(directory.getName()) != null) {
CCUtils.enableAction(event, true);
return;
}
@@ -22,12 +22,12 @@ import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiDirectory;
import com.intellij.psi.PsiElement;
import com.intellij.util.PlatformIcons;
import com.jetbrains.edu.courseFormat.Course;
import com.jetbrains.edu.courseFormat.Lesson;
import com.jetbrains.edu.courseFormat.Task;
import com.jetbrains.edu.coursecreator.CCLanguageManager;
import com.jetbrains.edu.coursecreator.CCProjectService;
import com.jetbrains.edu.coursecreator.CCUtils;
import com.jetbrains.edu.coursecreator.format.Course;
import com.jetbrains.edu.coursecreator.format.Lesson;
import com.jetbrains.edu.coursecreator.format.Task;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -55,7 +55,7 @@ public class CCCreateTask extends DumbAwareAction {
public static void createTask(final IdeView view, final Project project, final PsiDirectory lessonDir, boolean showDialog) {
final CCProjectService service = CCProjectService.getInstance(project);
final Course course = service.getCourse();
final Lesson lesson = course.getLesson(lessonDir.getName());
final Lesson lesson = service.getLesson(lessonDir.getName());
final int size = lesson.getTaskList().size();
final String taskName;
if (showDialog) {
@@ -81,7 +81,8 @@ public class CCCreateTask extends DumbAwareAction {
CCUtils.markDirAsSourceRoot(taskDirectory.getVirtualFile(), project);
final Task task = new Task(taskName);
task.setIndex(size + 1);
lesson.addTask(task, taskDirectory);
service.addTask(task, taskDirectory);
lesson.addTask(task);
createFromTemplateAndOpen(taskDirectory, manager.getTestsTemplate(project), view);
createFromTemplateAndOpen(taskDirectory, FileTemplateManager.getInstance(project).getInternalTemplate("task.html"), view);
@@ -157,7 +158,7 @@ public class CCCreateTask extends DumbAwareAction {
final PsiDirectory directory = DirectoryChooserUtil.getOrChooseDirectory(view);
final CCProjectService service = CCProjectService.getInstance(project);
final Course course = service.getCourse();
if (course != null && directory != null && course.getLesson(directory.getName()) == null) {
if (course != null && directory != null && service.getLesson(directory.getName()) == null) {
presentation.setVisible(false);
presentation.setEnabled(false);
return;
@@ -19,12 +19,11 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiDirectory;
import com.intellij.psi.PsiElement;
import com.jetbrains.edu.courseFormat.Course;
import com.jetbrains.edu.courseFormat.Task;
import com.jetbrains.edu.coursecreator.CCLanguageManager;
import com.jetbrains.edu.coursecreator.CCProjectService;
import com.jetbrains.edu.coursecreator.CCUtils;
import com.jetbrains.edu.coursecreator.CCLanguageManager;
import com.jetbrains.edu.coursecreator.format.Course;
import com.jetbrains.edu.coursecreator.format.Lesson;
import com.jetbrains.edu.coursecreator.format.Task;
import com.jetbrains.edu.coursecreator.ui.CreateTaskFileDialog;
import org.jetbrains.annotations.NotNull;
@@ -52,8 +51,7 @@ public class CCCreateTaskFile extends DumbAwareAction {
}
final CCProjectService service = CCProjectService.getInstance(project);
final Course course = service.getCourse();
final Lesson lesson = course.getLesson(lessonDir.getName());
final Task task = lesson.getTask(taskDir.getName());
final Task task = service.getTask(taskDir.getVirtualFile().getPath());
final int index = task.getTaskFiles().size() + 1;
String generatedName = "file" + index;
@@ -1,21 +1,19 @@
package com.jetbrains.edu.coursecreator.actions;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiFile;
import com.jetbrains.edu.courseFormat.AnswerPlaceholder;
import com.jetbrains.edu.courseFormat.TaskFile;
import com.jetbrains.edu.coursecreator.CCAnswerPlaceholderPainter;
import com.jetbrains.edu.coursecreator.CCProjectService;
import com.jetbrains.edu.coursecreator.format.AnswerPlaceholder;
import com.jetbrains.edu.coursecreator.format.Course;
import com.jetbrains.edu.coursecreator.format.TaskFile;
import org.jetbrains.annotations.NotNull;
import java.util.List;
public class CCDeleteTaskWindow extends CCTaskWindowAction {
private static final Logger LOG = Logger.getInstance(CCDeleteTaskWindow.class);
public CCDeleteTaskWindow() {
super("Delete Answer Placeholder","Delete answer placeholder", null);
@@ -27,18 +25,15 @@ public class CCDeleteTaskWindow extends CCTaskWindowAction {
PsiFile psiFile = state.getFile();
final Document document = PsiDocumentManager.getInstance(project).getDocument(psiFile);
if (document == null) return;
final CCProjectService service = CCProjectService.getInstance(project);
final Course course = service.getCourse();
TaskFile taskFile = state.getTaskFile();
AnswerPlaceholder answerPlaceholder = state.getAnswerPlaceholder();
final List<AnswerPlaceholder> answerPlaceholders = taskFile.getAnswerPlaceholders();
if (answerPlaceholders.contains(answerPlaceholder)) {
answerPlaceholder.removeResources(project);
answerPlaceholders.remove(answerPlaceholder);
final Editor editor = state.getEditor();
editor.getMarkupModel().removeAllHighlighters();
CCProjectService.getInstance(project).drawTaskWindows(psiFile.getVirtualFile(), editor);
taskFile.createGuardedBlocks(editor);
CCAnswerPlaceholderPainter.createGuardedBlocks(editor, taskFile);
}
}
}
@@ -26,8 +26,8 @@ import com.intellij.openapi.project.DumbAwareAction;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiDirectory;
import com.intellij.psi.PsiFile;
import com.jetbrains.edu.courseFormat.Course;
import com.jetbrains.edu.coursecreator.CCProjectService;
import com.jetbrains.edu.coursecreator.format.Course;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
@@ -18,8 +18,9 @@ package com.jetbrains.edu.coursecreator.actions;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.psi.PsiDirectory;
import com.jetbrains.edu.coursecreator.format.Course;
import com.jetbrains.edu.coursecreator.format.Lesson;
import com.jetbrains.edu.courseFormat.Course;
import com.jetbrains.edu.courseFormat.Lesson;
import com.jetbrains.edu.coursecreator.CCProjectService;
public class CCRenameLesson extends CCRename {
@@ -34,7 +35,7 @@ public class CCRenameLesson extends CCRename {
@Override
public boolean processRename(Project project, PsiDirectory directory, Course course) {
Lesson lesson = course.getLesson(directory.getName());
Lesson lesson = CCProjectService.getInstance(project).getLesson(directory.getName());
if (lesson == null) {
return false;
}
@@ -18,9 +18,10 @@ package com.jetbrains.edu.coursecreator.actions;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.psi.PsiDirectory;
import com.jetbrains.edu.coursecreator.format.Course;
import com.jetbrains.edu.coursecreator.format.Lesson;
import com.jetbrains.edu.coursecreator.format.Task;
import com.jetbrains.edu.courseFormat.Course;
import com.jetbrains.edu.courseFormat.Lesson;
import com.jetbrains.edu.courseFormat.Task;
import com.jetbrains.edu.coursecreator.CCProjectService;
public class CCRenameTask extends CCRename {
public CCRenameTask() {
@@ -38,11 +39,12 @@ public class CCRenameTask extends CCRename {
if (lessonDir == null || !lessonDir.getName().contains("lesson")) {
return false;
}
Lesson lesson = course.getLesson(lessonDir.getName());
final CCProjectService service = CCProjectService.getInstance(project);
Lesson lesson = service.getLesson(lessonDir.getName());
if (lesson == null) {
return false;
}
Task task = lesson.getTask(directory.getName());
Task task = service.getTask(directory.getVirtualFile().getPath());
if (task == null) {
return false;
}
@@ -34,12 +34,11 @@ 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.courseFormat.*;
import com.jetbrains.edu.coursecreator.CCLanguageManager;
import com.jetbrains.edu.coursecreator.CCProjectService;
import com.jetbrains.edu.coursecreator.CCUtils;
import com.jetbrains.edu.coursecreator.CCLanguageManager;
import com.jetbrains.edu.coursecreator.format.*;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.FileOutputStream;
import java.io.IOException;
@@ -79,15 +78,15 @@ public abstract class CCRunTestsAction extends AnAction {
final PsiDirectory lessonDir = taskDir.getParent();
if (lessonDir == null) return;
if (course == null) return;
final Lesson lesson = course.getLesson(lessonDir.getName());
final Lesson lesson = service.getLesson(lessonDir.getName());
if (lesson == null) return;
final Task task = lesson.getTask(taskDir.getName());
final Task task = service.getTask(taskDir.getVirtualFile().getPath());
if (task == null) {
presentation.setVisible(false);
presentation.setEnabled(false);
return;
}
TaskFile taskFile = task.getTaskFile(psiFile.getName());
TaskFile taskFile = service.getTaskFile(psiFile.getVirtualFile());
if (taskFile == null) {
LOG.info("could not find task file");
presentation.setVisible(false);
@@ -126,7 +125,7 @@ public abstract class CCRunTestsAction extends AnAction {
if (taskDir == null) {
return;
}
final Task task = getTask(course, taskDir);
final Task task = CCProjectService.getInstance(project).getTask(taskDir.getPath());
if (task == null) {
return;
}
@@ -208,23 +207,6 @@ public abstract class CCRunTestsAction extends AnAction {
@NotNull final VirtualFile taskDir,
@NotNull final VirtualFile testFile);
@Nullable
private static Task getTask(@NotNull final Course course, @NotNull final VirtualFile taskDir) {
if (!taskDir.getName().contains("task")) {
return null;
}
VirtualFile lessonDir = taskDir.getParent();
if (lessonDir == null || !lessonDir.getName().contains("lesson")) {
return null;
}
Lesson lesson = course.getLesson(lessonDir.getName());
if (lesson == null) {
return null;
}
return lesson.getTask(taskDir.getName());
}
//some tests could compare task files after user modifications with initial task files
private static void createResourceFiles(@NotNull final VirtualFile file, @NotNull final Project project) {
VirtualFile taskDir = file.getParent();
@@ -248,7 +230,6 @@ public abstract class CCRunTestsAction extends AnAction {
HashMap<TaskFile, TaskFile> taskFilesCopy = new HashMap<TaskFile, TaskFile>();
for (Map.Entry<String, TaskFile> entry : task.getTaskFiles().entrySet()) {
CCCreateCourseArchive.createUserFile(project, taskFilesCopy, taskResourceDir, taskDir, entry);
CCCreateCourseArchive.resetTaskFiles(taskFilesCopy);
}
}
}
@@ -282,7 +263,7 @@ public abstract class CCRunTestsAction extends AnAction {
printWriter = new PrintWriter(new FileOutputStream(windowsFile.getPath()));
for (AnswerPlaceholder answerPlaceholder : taskFile.getAnswerPlaceholders()) {
int start = answerPlaceholder.getRealStartOffset(document);
String windowDescription = document.getText(new TextRange(start, start + answerPlaceholder.getReplacementLength()));
String windowDescription = document.getText(new TextRange(start, start + answerPlaceholder.getPossibleAnswerLength()));
printWriter.println("#educational_plugin_window = " + windowDescription);
}
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@@ -33,8 +33,12 @@ import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiDirectory;
import com.intellij.psi.PsiFile;
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.CCAnswerPlaceholderPainter;
import com.jetbrains.edu.coursecreator.CCProjectService;
import com.jetbrains.edu.coursecreator.format.*;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
@@ -84,13 +88,13 @@ public class CCShowPreview extends DumbAwareAction {
if (lessonDir == null) {
return;
}
Course course = CCProjectService.getInstance(project).getCourse();
final CCProjectService service = CCProjectService.getInstance(project);
Course course = service.getCourse();
if (course == null) {
return;
}
Lesson lesson = course.getLesson(lessonDir.getName());
Task task = lesson.getTask(taskDir.getName());
TaskFile taskFile = task.getTaskFile(file.getName());
Task task = service.getTask(taskDir.getVirtualFile().getPath());
TaskFile taskFile = service.getTaskFile(file.getVirtualFile());
if (taskFile == null) {
return;
}
@@ -129,7 +133,7 @@ public class CCShowPreview extends DumbAwareAction {
}
});
for (AnswerPlaceholder answerPlaceholder : taskFile.getAnswerPlaceholders()) {
answerPlaceholder.drawHighlighter(createdEditor, true);
CCAnswerPlaceholderPainter.drawHighlighter(answerPlaceholder, createdEditor, true);
}
JPanel header = new JPanel();
header.setLayout(new BoxLayout(header, BoxLayout.Y_AXIS));
@@ -142,6 +146,5 @@ public class CCShowPreview extends DumbAwareAction {
createdEditor.setCaretEnabled(false);
showPreviewFrame.setComponent(labeledEditor);
showPreviewFrame.show();
CCCreateCourseArchive.resetTaskFiles(taskFilesCopy);
}
}
@@ -3,8 +3,11 @@ package com.jetbrains.edu.coursecreator.actions;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiDirectory;
import com.intellij.psi.PsiFile;
import com.jetbrains.edu.courseFormat.AnswerPlaceholder;
import com.jetbrains.edu.courseFormat.Lesson;
import com.jetbrains.edu.courseFormat.Task;
import com.jetbrains.edu.courseFormat.TaskFile;
import com.jetbrains.edu.coursecreator.CCProjectService;
import com.jetbrains.edu.coursecreator.format.*;
import com.jetbrains.edu.coursecreator.ui.CreateTaskWindowDialog;
import org.jetbrains.annotations.NotNull;
@@ -18,13 +21,12 @@ public class CCShowTaskWindowDetails extends CCTaskWindowAction {
protected void performTaskWindowAction(@NotNull CCState state) {
final Project project = state.getProject();
final CCProjectService service = CCProjectService.getInstance(project);
final Course course = service.getCourse();
PsiFile file = state.getFile();
final PsiDirectory taskDir = file.getContainingDirectory();
final PsiDirectory lessonDir = taskDir.getParent();
if (lessonDir == null) return;
final Lesson lesson = course.getLesson(lessonDir.getName());
final Task task = lesson.getTask(taskDir.getName());
final Lesson lesson = service.getLesson(lessonDir.getName());
final Task task = service.getTask(taskDir.getVirtualFile().getPath());
final TaskFile taskFile = state.getTaskFile();
AnswerPlaceholder answerPlaceholder = state.getAnswerPlaceholder();
CreateTaskWindowDialog dlg = new CreateTaskWindowDialog(project, answerPlaceholder, lesson.getIndex(), task.getIndex(),
@@ -8,9 +8,9 @@ import com.intellij.openapi.project.DumbAwareAction;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiFile;
import com.jetbrains.edu.courseFormat.AnswerPlaceholder;
import com.jetbrains.edu.courseFormat.TaskFile;
import com.jetbrains.edu.coursecreator.CCProjectService;
import com.jetbrains.edu.coursecreator.format.AnswerPlaceholder;
import com.jetbrains.edu.coursecreator.format.TaskFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -6,11 +6,11 @@ import com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiDirectory;
import com.intellij.ui.SimpleTextAttributes;
import com.jetbrains.edu.courseFormat.Course;
import com.jetbrains.edu.courseFormat.Lesson;
import com.jetbrains.edu.courseFormat.Task;
import com.jetbrains.edu.coursecreator.CCProjectService;
import com.jetbrains.edu.coursecreator.CCUtils;
import com.jetbrains.edu.coursecreator.format.Course;
import com.jetbrains.edu.coursecreator.format.Lesson;
import com.jetbrains.edu.coursecreator.format.Task;
import org.jetbrains.annotations.NotNull;
public class CCDirectoryNode extends PsiDirectoryNode {
@@ -30,7 +30,8 @@ public class CCDirectoryNode extends PsiDirectoryNode {
//TODO:change presentable name for files with suffix _answer
String valueName = myValue.getName();
final Course course = CCProjectService.getInstance(myProject).getCourse();
final CCProjectService service = CCProjectService.getInstance(myProject);
final Course course = service.getCourse();
if (course == null) return;
if (myProject.getBaseDir().equals(myValue.getVirtualFile())) {
data.clearText();
@@ -38,7 +39,7 @@ public class CCDirectoryNode extends PsiDirectoryNode {
data.addText(" (" + course.getName() + ")", SimpleTextAttributes.GRAYED_ATTRIBUTES);
return;
}
final Lesson lesson = course.getLesson(valueName);
final Lesson lesson = service.getLesson(valueName);
if (lesson != null) {
data.clearText();
data.addText(valueName, SimpleTextAttributes.REGULAR_ATTRIBUTES);
@@ -48,13 +49,13 @@ public class CCDirectoryNode extends PsiDirectoryNode {
else {
final PsiDirectory parentDir = myValue.getParentDirectory();
if (parentDir != null) {
final Lesson parentLesson = course.getLesson(parentDir.getName());
final Lesson parentLesson = service.getLesson(parentDir.getName());
if (parentLesson != null) {
final Task task = parentLesson.getTask(valueName);
final Task task = service.getTask(myValue.getVirtualFile().getPath());
if (task != null) {
data.clearText();
data.addText(valueName, SimpleTextAttributes.REGULAR_ATTRIBUTES);
data.addText(" (" + task.name + ")", SimpleTextAttributes.GRAYED_ATTRIBUTES);
data.addText(" (" + task.getName() + ")", SimpleTextAttributes.GRAYED_ATTRIBUTES);
return;
}
}
@@ -8,9 +8,9 @@ import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.ui.DoubleClickListener;
import com.intellij.ui.ListScrollingUtil;
import com.intellij.ui.components.JBList;
import com.jetbrains.edu.coursecreator.CCUtils;
import com.jetbrains.edu.courseFormat.Course;
import com.jetbrains.edu.coursecreator.CCLanguageManager;
import com.jetbrains.edu.coursecreator.format.Course;
import com.jetbrains.edu.coursecreator.CCUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -1,25 +1,18 @@
package com.jetbrains.edu.coursecreator.ui;
import com.intellij.ide.projectView.ProjectView;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.ValidationInfo;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileManager;
import com.jetbrains.edu.coursecreator.CCProjectService;
import com.jetbrains.edu.coursecreator.format.AnswerPlaceholder;
import com.jetbrains.edu.courseFormat.AnswerPlaceholder;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.io.*;
public class CreateTaskWindowDialog extends DialogWrapper {
private static final String ourTitle = "Add Answer Placeholder";
private static final Logger LOG = Logger.getInstance(CreateTaskWindowDialog.class.getName());
private final AnswerPlaceholder myAnswerPlaceholder;
private final CreateTaskWindowPanel myPanel;
private final Project myProject;
@@ -36,124 +29,35 @@ public class CreateTaskWindowDialog extends DialogWrapper {
myPanel = new CreateTaskWindowPanel(this);
String generatedHintName = "lesson" + lessonIndex + "task" + taskIndex + taskFileName + "_" + taskWindowIndex;
myPanel.setGeneratedHintName(generatedHintName);
if (answerPlaceholder.getHintName() != null) {
setHintText(project, answerPlaceholder);
if (answerPlaceholder.getHint() != null) {
setHintText(answerPlaceholder);
}
myProject = project;
String taskWindowTaskText = answerPlaceholder.getTaskText();
myPanel.setTaskWindowText(taskWindowTaskText != null ? taskWindowTaskText : "");
String hintName = answerPlaceholder.getHintName();
myPanel.setHintName(hintName != null ? hintName : "");
String hintName = answerPlaceholder.getHint();
myPanel.setHintText(hintName != null ? hintName : "");
init();
initValidation();
}
@SuppressWarnings("IOResourceOpenedButNotSafelyClosed")
private void setHintText(Project project, AnswerPlaceholder answerPlaceholder) {
VirtualFile hints = project.getBaseDir().findChild("hints");
if (hints != null) {
File file = new File(hints.getPath(), answerPlaceholder.getHintName());
StringBuilder hintText = new StringBuilder();
if (file.exists()) {
BufferedReader bufferedReader = null;
try {
bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8"));
String line;
while ((line = bufferedReader.readLine()) != null) {
hintText.append(line).append("\n");
}
myPanel.doClick();
//myPanel.enableHint(true);
myPanel.setHintText(hintText.toString());
}
catch (FileNotFoundException e) {
LOG.error("created hint was not found", e);
}
catch (IOException e) {
LOG.error(e);
}
finally {
if (bufferedReader != null) {
try {
bufferedReader.close();
}
catch (IOException e) {
//close silently
}
}
}
}
}
private void setHintText(AnswerPlaceholder answerPlaceholder) {
String hintText = answerPlaceholder.getHint();
myPanel.doClick();
myPanel.setHintText(hintText);
}
@Override
protected void doOKAction() {
String taskWindowText = myPanel.getAnswerPlaceholderText();
myAnswerPlaceholder.setTaskText(StringUtil.notNullize(taskWindowText));
if (myPanel.createHint()) {
String hintName = myPanel.getHintName();
myAnswerPlaceholder.setHint(hintName);
String hintText = myPanel.getHintText();
createHint(hintName, hintText);
} else {
if (myAnswerPlaceholder.getHintName() != null) {
deleteHint();
}
}
myAnswerPlaceholder.setLength(StringUtil.notNullize(taskWindowText).length());
myAnswerPlaceholder.setHint(myPanel.getHintText());
super.doOKAction();
}
@SuppressWarnings("IOResourceOpenedButNotSafelyClosed")
private void createHint(String hintName, String hintText) {
VirtualFile hintsDir = myProject.getBaseDir().findChild("hints");
if (hintsDir != null) {
File hintFile = new File(hintsDir.getPath(), hintName);
OutputStreamWriter outputStreamWriter = null;
try {
outputStreamWriter = new OutputStreamWriter(new FileOutputStream(hintFile), "UTF-8");
outputStreamWriter.write(hintText);
}
catch (FileNotFoundException e) {
//TODO:show error in UI
return;
}
catch (UnsupportedEncodingException e) {
LOG.error(e);
}
catch (IOException e) {
LOG.error(e);
}
finally {
if (outputStreamWriter != null) {
try {
outputStreamWriter.close();
}
catch (IOException e) {
//close silently
}
}
}
}
VirtualFileManager.getInstance().refreshWithoutFileWatcher(true);
ProjectView.getInstance(myProject).refresh();
}
private void deleteHint() {
VirtualFile hintsDir = myProject.getBaseDir().findChild("hints");
if (hintsDir != null) {
String hintName = myAnswerPlaceholder.getHintName();
if (hintName == null) {
return;
}
File hintFile = new File(hintsDir.getPath(), hintName);
if (hintFile.exists()) {
CCProjectService.deleteProjectFile(hintFile, myProject);
myAnswerPlaceholder.setHint(null);
myPanel.resetHint();
}
}
}
@Nullable
@Override
protected JComponent createCenterPanel() {
@@ -163,20 +67,7 @@ public class CreateTaskWindowDialog extends DialogWrapper {
@Nullable
@Override
public ValidationInfo doValidate() {
String name = myPanel.getHintName();
VirtualFile hintsDir = myProject.getBaseDir().findChild("hints");
if (hintsDir == null) {
return null;
}
VirtualFile child = hintsDir.findChild(name);
if (child == null) {
return null;
}
return myAnswerPlaceholder.getHintName() != null ? null : new ValidationInfo("Hint file with such filename already exists");
}
public void validateInput() {
super.initValidation();
return myAnswerPlaceholder.getHint() != null ? null : new ValidationInfo("Type hint");
}
@Nullable
@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.jetbrains.edu.coursecreator.ui.CreateTaskWindowPanel">
<grid id="27dc6" binding="myPanel" layout-manager="GridLayoutManager" row-count="4" column-count="4" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<grid id="27dc6" binding="myPanel" layout-manager="GridLayoutManager" row-count="3" column-count="4" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<xy x="20" y="20" width="450" height="209"/>
<xy x="20" y="20" width="450" height="177"/>
</constraints>
<properties/>
<border type="none"/>
@@ -16,29 +16,9 @@
<text value="Placeholder text:"/>
</properties>
</component>
<component id="d2e2f" class="javax.swing.JLabel" binding="myHintNameLabel">
<constraints>
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="4" use-parent-layout="false"/>
</constraints>
<properties>
<enabled value="true"/>
<labelFor value="ddeb1"/>
<text value="ID:"/>
</properties>
</component>
<component id="ddeb1" class="javax.swing.JTextField" binding="myHintName">
<constraints>
<grid row="2" column="1" row-span="1" col-span="3" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
<preferred-size width="150" height="-1"/>
</grid>
</constraints>
<properties>
<text value=""/>
</properties>
</component>
<component id="d322a" class="javax.swing.JLabel" binding="myHintTextLabel">
<constraints>
<grid row="3" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="9" fill="0" indent="4" use-parent-layout="false"/>
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="9" fill="0" indent="4" use-parent-layout="false"/>
</constraints>
<properties>
<labelFor value="d0efc"/>
@@ -48,7 +28,7 @@
<grid id="51a63" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="3" column="1" row-span="1" col-span="3" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
<grid row="2" column="1" row-span="1" col-span="3" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="line">
@@ -1,9 +1,6 @@
package com.jetbrains.edu.coursecreator.ui;
import com.intellij.ui.DocumentAdapter;
import javax.swing.*;
import javax.swing.event.DocumentEvent;
import java.awt.*;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
@@ -12,10 +9,8 @@ public class CreateTaskWindowPanel extends JPanel {
private final CreateTaskWindowDialog myDialog;
private JPanel myPanel;
private JTextField myHintName;
private JTextArea myHintText;
private JCheckBox myCreateHintCheckBox;
private JLabel myHintNameLabel;
private JLabel myHintTextLabel;
private JTextField myTaskWindowText;
private String myGeneratedHintName = "";
@@ -38,30 +33,17 @@ public class CreateTaskWindowPanel extends JPanel {
});
myTaskWindowText.grabFocus();
myHintName.getDocument().addDocumentListener(new DocumentAdapter() {
@Override
protected void textChanged(DocumentEvent e) {
myDialog.validateInput();
}
});
}
private void enableHint(boolean isEnable) {
myHintName.setEnabled(isEnable);
myHintText.setEnabled(isEnable);
myHintNameLabel.setEnabled(isEnable);
myHintTextLabel.setEnabled(isEnable);
myHintName.setText(myGeneratedHintName);
}
public void setTaskWindowText(String taskWindowText) {
myTaskWindowText.setText(taskWindowText);
}
public void setHintName(String hintName) {
myHintName.setText(hintName);
}
public void setHintText(String hintText) {
myHintText.setText(hintText);
}
@@ -70,24 +52,15 @@ public class CreateTaskWindowPanel extends JPanel {
return myTaskWindowText.getText();
}
public String getHintName() {
return myHintName.getText();
}
public String getHintText() {
return myHintText.getText();
}
public boolean createHint() {
return myHintName.isEnabled();
}
public void doClick() {
myCreateHintCheckBox.doClick();
}
public void resetHint() {
myHintName.setText("");
myHintText.setText("");
}
@@ -12,7 +12,6 @@ import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.Collections;
import java.util.List;
import java.util.Map;
@@ -159,7 +158,7 @@ public class StudyGenerator {
for (AnswerPlaceholder answerPlaceholder : answerPlaceholders) {
initAnswerPlaceholder(answerPlaceholder, taskFile, isRestarted);
}
Collections.sort(answerPlaceholders);
//Collections.sort(answerPlaceholders);
for (int i = 0; i < answerPlaceholders.size(); i++) {
answerPlaceholders.get(i).setIndex(i);
}
@@ -5,12 +5,13 @@ import com.google.gson.annotations.SerializedName;
import com.intellij.openapi.editor.Document;
import com.intellij.util.xmlb.annotations.Transient;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* Implementation of windows which user should type in
*/
public class AnswerPlaceholder implements Comparable {
public class AnswerPlaceholder {
@Expose private int line = 0;
@Expose private int start = 0;
@@ -61,7 +62,7 @@ public class AnswerPlaceholder implements Comparable {
return hint;
}
public void setHint(@NotNull final String hint) {
public void setHint(@Nullable final String hint) {
this.hint = hint;
}
@@ -81,6 +82,14 @@ public class AnswerPlaceholder implements Comparable {
myInitialState = initialState;
}
public String getTaskText() {
return myTaskText;
}
public void setTaskText(String taskText) {
myTaskText = taskText;
}
@Transient
public TaskFile getTaskFile() {
return myTaskFile;
@@ -95,6 +104,10 @@ public class AnswerPlaceholder implements Comparable {
return document.getLineStartOffset(line) + start;
}
public int getPossibleAnswerLength() {
return possibleAnswer.length();
}
public boolean isValid(@NotNull final Document document) {
boolean isLineValid = line < document.getLineCount() && line >= 0;
if (!isLineValid) return false;
@@ -103,18 +116,6 @@ public class AnswerPlaceholder implements Comparable {
return isLengthValid && isStartValid;
}
public int compareTo(@NotNull Object o) {
AnswerPlaceholder answerPlaceholder = (AnswerPlaceholder)o;
if (answerPlaceholder.getTaskFile() != myTaskFile) {
throw new ClassCastException();
}
int lineDiff = line - answerPlaceholder.line;
if (lineDiff == 0) {
return start - answerPlaceholder.start;
}
return lineDiff;
}
/**
* Returns window to its initial state
*/
@@ -2,6 +2,7 @@ package com.jetbrains.edu.courseFormat;
import com.google.gson.annotations.SerializedName;
import com.intellij.util.xmlb.annotations.Transient;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
@@ -53,4 +54,8 @@ public class Lesson {
public void setCourse(Course course) {
myCourse = course;
}
public void addTask(@NotNull final Task task) {
taskList.add(task);
}
}
@@ -23,6 +23,12 @@ public class Task {
@Transient private Lesson myLesson;
public Task() {}
public Task(@NotNull final String name) {
this.name = name;
}
public String getName() {
return name;
}
@@ -59,10 +65,21 @@ public class Task {
return taskFiles;
}
@Nullable
public TaskFile getTaskFile(final String name) {
return name != null ? taskFiles.get(name) : null;
}
public boolean isTaskFile(@NotNull final String fileName) {
return taskFiles.get(fileName) != null;
}
public void addTaskFile(@NotNull final String name, int index) {
TaskFile taskFile = new TaskFile();
taskFile.setIndex(index);
taskFiles.put(name, taskFile);
}
@Nullable
public TaskFile getFile(@NotNull final String fileName) {
return taskFiles.get(fileName);
@@ -53,6 +53,10 @@ public class TaskFile {
this.myAnswerPlaceholders = answerPlaceholders;
}
public void addAnswerPlaceholder(AnswerPlaceholder answerPlaceholder) {
myAnswerPlaceholders.add(answerPlaceholder);
}
public int getIndex() {
return myIndex;
}
@@ -112,7 +116,6 @@ public class TaskFile {
target.setAnswerPlaceholders(windowsCopy);
}
public void setUserCreated(boolean userCreated) {
myUserCreated = userCreated;
}