mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
reused course format in course creator plugin
//TODO: answer placeholders sort extract painter
This commit is contained in:
@@ -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">
|
||||
|
||||
+174
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+5
-4
@@ -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 )));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+7
-10
@@ -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
|
||||
|
||||
+19
-17
@@ -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;
|
||||
}
|
||||
|
||||
+64
-31
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+8
-7
@@ -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;
|
||||
|
||||
|
||||
+25
-19
@@ -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);
|
||||
+1
-1
@@ -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;
|
||||
|
||||
+18
-30
@@ -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");
|
||||
|
||||
+20
-15
@@ -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;
|
||||
}
|
||||
|
||||
+7
-6
@@ -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;
|
||||
|
||||
+4
-6
@@ -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;
|
||||
|
||||
+4
-9
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -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.*;
|
||||
|
||||
+4
-3
@@ -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;
|
||||
}
|
||||
|
||||
+7
-5
@@ -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;
|
||||
}
|
||||
|
||||
+7
-26
@@ -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() {
|
||||
|
||||
+10
-7
@@ -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);
|
||||
}
|
||||
}
|
||||
+6
-4
@@ -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(),
|
||||
|
||||
+2
-2
@@ -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;
|
||||
|
||||
|
||||
+9
-8
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -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;
|
||||
|
||||
|
||||
+13
-122
@@ -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
|
||||
|
||||
+4
-24
@@ -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">
|
||||
|
||||
-27
@@ -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("");
|
||||
}
|
||||
|
||||
|
||||
+1
-2
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user