reused course format in course creator plugin
authorEkaterina Tuzova <Ekaterina.Tuzova@jetbrains.com>
Sat, 14 Feb 2015 14:29:44 +0000 (17:29 +0300)
committerEkaterina Tuzova <Ekaterina.Tuzova@jetbrains.com>
Sat, 14 Feb 2015 14:29:44 +0000 (17:29 +0300)
//TODO: answer placeholders sort
extract painter

36 files changed:
python/edu/course-creator-python/course-creator-python.iml
python/edu/course-creator-python/src/com/jetbrains/edu/coursecreator/PyCCProjectGenerator.java
python/edu/course-creator-python/tests/CCDocumentListenerTest.java
python/educational/course-creator/course-creator.iml
python/educational/course-creator/resources/META-INF/plugin.xml
python/educational/course-creator/src/com/jetbrains/edu/coursecreator/CCAnswerPlaceholderPainter.java [new file with mode: 0644]
python/educational/course-creator/src/com/jetbrains/edu/coursecreator/CCDocumentListener.java
python/educational/course-creator/src/com/jetbrains/edu/coursecreator/CCEditorFactoryListener.java
python/educational/course-creator/src/com/jetbrains/edu/coursecreator/CCProjectComponent.java
python/educational/course-creator/src/com/jetbrains/edu/coursecreator/CCProjectService.java
python/educational/course-creator/src/com/jetbrains/edu/coursecreator/CCRefactoringElementListenerProvider.java
python/educational/course-creator/src/com/jetbrains/edu/coursecreator/CCUtils.java
python/educational/course-creator/src/com/jetbrains/edu/coursecreator/actions/CCAddAnswerPlaceholder.java [moved from python/educational/course-creator/src/com/jetbrains/edu/coursecreator/actions/CCAddTaskWindow.java with 78% similarity]
python/educational/course-creator/src/com/jetbrains/edu/coursecreator/actions/CCChangeCourseInfo.java
python/educational/course-creator/src/com/jetbrains/edu/coursecreator/actions/CCCreateCourseArchive.java
python/educational/course-creator/src/com/jetbrains/edu/coursecreator/actions/CCCreateLesson.java
python/educational/course-creator/src/com/jetbrains/edu/coursecreator/actions/CCCreateTask.java
python/educational/course-creator/src/com/jetbrains/edu/coursecreator/actions/CCCreateTaskFile.java
python/educational/course-creator/src/com/jetbrains/edu/coursecreator/actions/CCDeleteTaskWindow.java
python/educational/course-creator/src/com/jetbrains/edu/coursecreator/actions/CCRename.java
python/educational/course-creator/src/com/jetbrains/edu/coursecreator/actions/CCRenameLesson.java
python/educational/course-creator/src/com/jetbrains/edu/coursecreator/actions/CCRenameTask.java
python/educational/course-creator/src/com/jetbrains/edu/coursecreator/actions/CCRunTestsAction.java
python/educational/course-creator/src/com/jetbrains/edu/coursecreator/actions/CCShowPreview.java
python/educational/course-creator/src/com/jetbrains/edu/coursecreator/actions/CCShowTaskWindowDetails.java
python/educational/course-creator/src/com/jetbrains/edu/coursecreator/actions/CCTaskWindowAction.java
python/educational/course-creator/src/com/jetbrains/edu/coursecreator/projectView/CCDirectoryNode.java
python/educational/course-creator/src/com/jetbrains/edu/coursecreator/ui/CreateTaskFileDialog.java
python/educational/course-creator/src/com/jetbrains/edu/coursecreator/ui/CreateTaskWindowDialog.java
python/educational/course-creator/src/com/jetbrains/edu/coursecreator/ui/CreateTaskWindowPanel.form
python/educational/course-creator/src/com/jetbrains/edu/coursecreator/ui/CreateTaskWindowPanel.java
python/educational/interactive-learning/src/com/jetbrains/edu/learning/courseGeneration/StudyGenerator.java
python/educational/src/com/jetbrains/edu/courseFormat/AnswerPlaceholder.java
python/educational/src/com/jetbrains/edu/courseFormat/Lesson.java
python/educational/src/com/jetbrains/edu/courseFormat/Task.java
python/educational/src/com/jetbrains/edu/courseFormat/TaskFile.java

index e08d029ad3ceb0b5603f3e483cc1a0c1f4e4bd7e..1f8e332757fde7eed84fb41536e3acb9eee3e06a 100644 (file)
@@ -14,5 +14,6 @@
     <orderEntry type="module" module-name="python-community" />
     <orderEntry type="module" module-name="testFramework" scope="TEST" />
     <orderEntry type="module" module-name="python-ide-community" />
+    <orderEntry type="module" module-name="educational" />
   </component>
 </module>
\ No newline at end of file
index d5f73de1e69e226f63b86695d3c254863d64c984..7ce529f1e6763ce56ab3db5381f4b67bedad00fc 100644 (file)
@@ -15,9 +15,9 @@ import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.platform.DirectoryProjectGenerator;
 import com.intellij.psi.PsiDirectory;
 import com.intellij.psi.PsiManager;
+import com.jetbrains.edu.courseFormat.Course;
 import com.jetbrains.edu.coursecreator.actions.CCCreateLesson;
 import com.jetbrains.edu.coursecreator.actions.CCCreateTask;
-import com.jetbrains.edu.coursecreator.format.Course;
 import com.jetbrains.edu.coursecreator.ui.CCNewProjectPanel;
 import com.jetbrains.python.newProject.PythonProjectGenerator;
 import icons.CourseCreatorPythonIcons;
@@ -63,7 +63,10 @@ public class PyCCProjectGenerator extends PythonProjectGenerator implements Dire
                                      @NotNull final String description) {
 
     final CCProjectService service = CCProjectService.getInstance(project);
-    final Course course = new Course(name, author, description);
+    final Course course = new Course();
+    course.setName(name);
+    course.setAuthor(author);
+    course.setDescription(description);
     course.setLanguage("Python");
     service.setCourse(course);
 
@@ -79,7 +82,7 @@ public class PyCCProjectGenerator extends PythonProjectGenerator implements Dire
         catch (Exception ignored) {
         }
         DirectoryUtil.createSubdirectories("hints", projectDir, "\\/");
-        final PsiDirectory lessonDir = CCCreateLesson.createLessonDir(projectDir, 1, null, null, course);
+        final PsiDirectory lessonDir = CCCreateLesson.createLessonDir(project, 1, null, null, course);
         CCCreateTask.createTask(null, project, lessonDir, false);
       }
     }.execute();
index 87e2548a14063c46add129b6f484571aba173747..23170c21802551a107f9192fdccc4ccf5e8a7fec 100644 (file)
@@ -5,9 +5,9 @@ import com.intellij.openapi.fileEditor.FileDocumentManager;
 import com.intellij.openapi.project.Project;
 import com.intellij.psi.PsiFile;
 import com.intellij.util.xmlb.XmlSerializer;
+import com.jetbrains.edu.courseFormat.AnswerPlaceholder;
+import com.jetbrains.edu.courseFormat.TaskFile;
 import com.jetbrains.edu.coursecreator.actions.CCCreateCourseArchive;
-import com.jetbrains.edu.coursecreator.format.AnswerPlaceholder;
-import com.jetbrains.edu.coursecreator.format.TaskFile;
 import org.jdom.input.SAXBuilder;
 import org.jetbrains.annotations.NotNull;
 
@@ -57,7 +57,7 @@ public class CCDocumentListenerTest extends CCTestCase {
         ApplicationManager.getApplication().runWriteAction(new Runnable() {
           @Override
           public void run() {
-            document.replaceString(offset, offset + answerPlaceholder.getReplacementLength(), taskText);
+            document.replaceString(offset, offset + answerPlaceholder.getPossibleAnswer().length(), taskText);
             FileDocumentManager.getInstance().saveDocument(document);
           }
         });
index 75a2690f8e0f2369d3159c79e406aaa5330b3425..b54f05e2bd7e906b60057a023a3864855219cbd1 100644 (file)
@@ -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>
\ No newline at end of file
index 3aee001aecbc056e5d4ca6ee4c8ce5affbcbd287..200574534a0523265b14c8ad52b1a8cfb8b3a03b 100644 (file)
@@ -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">
diff --git a/python/educational/course-creator/src/com/jetbrains/edu/coursecreator/CCAnswerPlaceholderPainter.java b/python/educational/course-creator/src/com/jetbrains/edu/coursecreator/CCAnswerPlaceholderPainter.java
new file mode 100644 (file)
index 0000000..9b2d236
--- /dev/null
@@ -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);
+      }
+    }
+  }
+
+}
index 3519701a024a4f1b5145154978a4c883b47647b6..c03a099026a4e2170a82b818ecba1467c54469e6 100644 (file)
@@ -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 )));
         }
       }
     }
index ad6b4439237571f92b64a2e4d2ca9c6503c8a689..eb9445ab289627380238489d16125420f1d3f857 100644 (file)
@@ -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
index e4c44a97e62fbf71827a8c85ab517c98952b4478..710843b57967e39f1f1f3c00768013f244c80175 100644 (file)
@@ -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;
       }
index cbf3d1d118b9eab4b905cfc29c6bc32d79d5ed4c..2d950285b832bf22228d8fdb7d83a3b70f74a56f 100644 (file)
@@ -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);
+  }
+
 }
index 50a4693d29ccb4c94a9ed9deff0fcd7b285feec3..1f238337e1088c804108dea2c042493339eb4f07 100644 (file)
@@ -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;
       }
index f5ca9378eebf4c04e3d1c1c4f2181857e16eb3db..059e56b2a81d5775454b87535cf681564d332cbf 100644 (file)
@@ -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;
 
similarity index 78%
rename from python/educational/course-creator/src/com/jetbrains/edu/coursecreator/actions/CCAddTaskWindow.java
rename to python/educational/course-creator/src/com/jetbrains/edu/coursecreator/actions/CCAddAnswerPlaceholder.java
index 6e9b7892059155a81a501981049b38b226d75bcd..406fbe69cda8dc49902f4846f582dde80d11eed8 100644 (file)
@@ -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);
index 81ee890989bb3662f70fce50f0bef94f29c7e9f7..1625f6361c161c8fd0137dbe8a1c7652740fad29 100644 (file)
@@ -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;
index 1857f9d75c3a6ac628acbaedc01c4267ae7ba3bd..0c6fbe30320b368b33c9206c47086fb719d01bdf 100644 (file)
@@ -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");
index 0866d4e206c4b9a5a29873cf7a412d08ac232eb3..0489c0104880b3dcbb3bba9b137b375a6a6c3a89 100644 (file)
@@ -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;
     }
index 85b2a6d5b19d2e997f8cab8390db158fb82b69c4..b6f17573197b2606b4789dffb16338efcf6e20d4 100644 (file)
@@ -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;
index 5483b1ef8eaaddf24f31190c606c973e9547f541..58e9474000ce8eaab5ffac61fab6211bff2f3161 100644 (file)
@@ -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;
index 0880006095b9508439fcba9ec37fca456af41d9f..b5ca452f53a14e34c7b79ee200d05c766968cbe7 100644 (file)
@@ -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);
     }
   }
 }
\ No newline at end of file
index 62212389b8d5153bae6308303eaeeafe9fc8b30e..e96bc902e70f2b1f0c85288f1a9823c3ad90a080 100644 (file)
@@ -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.*;
index eaea9bf7e0adf9abae9413ca1431420a2872fb0d..fc8d819fb2a0575d063608d96e0dff96880d29bb 100644 (file)
@@ -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;
     }
index 4690d0d1993f238397ebbb55c02e74fdad054da7..40d99f7392c35debc670c03cb9d6fb01c214cf34 100644 (file)
@@ -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;
     }
index f20ca9ab1aaddc1688214f383792e41b6502ef2e..251cd167eb9edd9963f9660cc33e6e76597c372e 100644 (file)
@@ -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() {
index a62134edd1969d210df621660f4eeddcd32fa898..d61cbcb99f0a3761208bcb5ce4c84185e354a2ff 100644 (file)
@@ -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);
   }
 }
\ No newline at end of file
index 73336433d016ba57a28a98a858b80009962fcb6a..b4c955091d0537769308a3c402b9937a87ddf4b3 100644 (file)
@@ -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(),
index 1334a743d389af6e55da4d02ed85f77b2b5978b4..a01c56a2c1a8784ecb07c6f5277ec9629432caff 100644 (file)
@@ -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;
 
index 4e861a8ea33ac5fdbb3bd6cc3fb3b136b5d9dd36..2f6a628711fb3409b21ac5aee419e2d3b0567b8e 100644 (file)
@@ -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;
           }
         }
index 9f3afb1b32c04688ee2a8286695e40a3b9ff58af..4b496ec6c1cf61db75ad0109fb1f356169d4ed97 100644 (file)
@@ -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;
 
index c7efd81baf72eb53320ce9a4206512fc182592ba..858b0e933040267144c469cb204724831070ac9c 100644 (file)
@@ -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
index 182dd58629e84bf220db56c9269781b25158e9c6..4de02982ef9ac0a8398bf69da0e4443a446f3851 100644 (file)
@@ -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"/>
           <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">
index 96c6b92883799cebcecdf72756487881ef7b5415..5bfda1b3a0445086f7d92977a35e397363e2887b 100644 (file)
@@ -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("");
   }
 
index 185edb35df41d337ba526332900c85cd77db6d7c..3ca1671cec199e2f23dfde2b6e22a1297e7c113b 100644 (file)
@@ -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);
     }
index 49d04b840aef02b1f8845b3788ebfe9ca84a46a6..b4f7af7f92db4cfdd3a1d4cba3c9127555501176 100644 (file)
@@ -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
    */
index be451ca17fff06c1a23f46ac7d81b849c0c7c64e..e697476d784683b2d76f8ddbc57706d1129d5c6c 100644 (file)
@@ -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);
+  }
 }
index 588a1d0808a00187f47981ef0000cd1c25c67d50..7ba1b3e9d217ed176f5d6b08538e9d960bfd582b 100644 (file)
@@ -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);
index 25230e68b9aefc3c166ddfeb57d237e5c83ae973..f98b1bc19bb7a973c357e19dc167aebb7ddfe2e9 100644 (file)
@@ -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;
   }