Resolve conflicts
authorValentina Kiryushkina <valentina.kiryushkina@jetbrains.com>
Wed, 18 May 2016 09:51:46 +0000 (12:51 +0300)
committerValentina Kiryushkina <valentina.kiryushkina@jetbrains.com>
Wed, 18 May 2016 09:51:46 +0000 (12:51 +0300)
14 files changed:
1  2 
python/educational-core/student/resources/META-INF/plugin.xml
python/educational-core/student/src/com/jetbrains/edu/learning/StudyBasePluginConfigurator.java
python/educational-core/student/src/com/jetbrains/edu/learning/StudyTaskManager.java
python/educational-core/student/src/com/jetbrains/edu/learning/StudyUtils.java
python/educational-core/student/src/com/jetbrains/edu/learning/checker/StudyCheckUtils.java
python/educational-core/student/src/com/jetbrains/edu/learning/courseFormat/Course.java
python/educational-core/student/src/com/jetbrains/edu/learning/ui/StudyJavaFxToolWindow.java
python/educational-core/student/src/com/jetbrains/edu/learning/ui/StudyNewProjectPanel.java
python/educational-core/student/src/com/jetbrains/edu/learning/ui/StudySwingToolWindow.java
python/educational-core/student/src/com/jetbrains/edu/learning/ui/StudyToolWindow.java
python/educational-core/student/src/com/jetbrains/edu/learning/ui/StudyToolWindowFactory.java
python/educational-core/student/student.iml
python/educational-python/resources/fileTemplates/internal/test_helper.py.ft
python/educational-python/student-python/src/com/jetbrains/edu/learning/PyStudyCheckAction.java

index 40da8f72175ca1b5cde4c91767077d99496bed2a,024cd09e924590fa9666f1acfc1a660911fca220..82942814d2f8dc452a6ac962cd227a53162ab40c
@@@ -14,7 -14,7 +14,8 @@@ import com.intellij.util.xmlb.XmlSerial
  import com.jetbrains.edu.learning.core.EduUtils;
  import com.jetbrains.edu.learning.courseFormat.*;
  import com.jetbrains.edu.learning.oldCourseFormat.OldCourse;
 +import com.jetbrains.edu.learning.stepic.StepicUser;
+ import com.jetbrains.edu.learning.ui.StudyToolWindow;
  import org.jdom.Element;
  import org.jetbrains.annotations.NotNull;
  import org.jetbrains.annotations.Nullable;
@@@ -209,7 -211,7 +213,8 @@@ public class StudyTaskManager implement
          myInvisibleFiles = taskManager.myInvisibleFiles;
          myTaskStatusMap = taskManager.myTaskStatusMap;
          myStudyStatusMap = taskManager.myStudyStatusMap;
+         myShouldUseJavaFx = taskManager.myShouldUseJavaFx;
 +        myUser = taskManager.getUser();
        }
      }
      final Element oldCourseElement = state.getChild(COURSE_ELEMENT);
      return myInvisibleFiles.contains(path);
    }
  
+   public boolean shouldUseJavaFx() {
+     return myShouldUseJavaFx;
+   }
+   public void setShouldUseJavaFx(boolean shouldUseJavaFx) {
+     this.myShouldUseJavaFx = shouldUseJavaFx;
+   }
+   public StudyToolWindow.StudyToolWindowMode getToolWindowMode() {
+     return myToolWindowMode;
+   }
+   public void setToolWindowMode(StudyToolWindow.StudyToolWindowMode toolWindowMode) {
+     myToolWindowMode = toolWindowMode;
+   }
+   public boolean isTurnEditingMode() {
+     return myTurnEditingMode;
+   }
+   public void setTurnEditingMode(boolean turnEditingMode) {
+     myTurnEditingMode = turnEditingMode;
+   }
++
 +  public String getLogin() {
 +    if (myUser != null) {
 +      return myUser.getEmail();
 +    }
 +    return "";
 +  }
 +
 +  public String getPassword() {
 +    if (myUser != null) {
 +      return myUser.getPassword();
 +    }
 +    return "";
 +  }
 +
 +  public void setLogin(String login) {
 +    if (myUser != null) {
 +      myUser.setEmail(login);
 +    }
 +  }
 +
 +  public void setPassword(String password) {
 +    if (myUser != null) {
 +      myUser.setPassword(password);
 +    }
 +  }
 +
 +  public StepicUser getUser() {
 +    return myUser;
 +  }
 +
 +  public void setUser(StepicUser user) {
 +    myUser = user;
 +  }
  }
index eee4250e8f6c824d5d6267a3c88155a6ff3e6e7d,2c41cda8d574f76a3a7b74573874c4fe3a55be37..63f6d29180f4eb9e6d6c9b9d7324788d992c1455
@@@ -361,9 -359,9 +361,9 @@@ public class StudyUtils 
      String lessonDir = EduNames.LESSON + String.valueOf(task.getLesson().getIndex());
      String taskDir = EduNames.TASK + String.valueOf(task.getIndex());
      Course course = task.getLesson().getCourse();
 -    File resourceFile = new File(course.getCourseDirectory());
 +    File resourceFile = getCourseDirectory(project, course);
      if (!resourceFile.exists()) {
-       return  null;
+       return null;
      }
      String patternPath = FileUtil.join(resourceFile.getPath(), lessonDir, taskDir, name);
      VirtualFile patternFile = VfsUtil.findFileByIoFile(new File(patternPath), true);
      return null;
    }
  
 -
 +  @Nullable
    public static String getTaskText(@NotNull final Project project) {
-     VirtualFile[] files = FileEditorManager.getInstance(project).getSelectedFiles();
-     TaskFile taskFile = null;
-     for (VirtualFile file : files) {
-       taskFile = getTaskFile(project, file);
-       if (taskFile != null) {
-         break;
-       }
-     }
+     TaskFile taskFile = getSelectedTaskFile(project);
      if (taskFile == null) {
        return EMPTY_TASK_TEXT;
      }
      }
      return null;
    }
+   @Nullable
+   public static TaskFile getSelectedTaskFile(@NotNull Project project) {
+     VirtualFile[] files = FileEditorManager.getInstance(project).getSelectedFiles();
+     TaskFile taskFile = null;
+     for (VirtualFile file : files) {
+       taskFile = getTaskFile(project, file);
+       if (taskFile != null) {
+         break;
+       }
+     }
+     return taskFile;
+   }
 +  
 +  @Nullable
 +  public static Task getCurrentTask(@NotNull final Project project) {
 +    VirtualFile[] files = FileEditorManager.getInstance(project).getSelectedFiles();
 +    TaskFile taskFile = null;
 +    for (VirtualFile file : files) {
 +      taskFile = getTaskFile(project, file);
 +      if (taskFile != null) {
 +        break;
 +      }
 +    }
 +    if (taskFile != null) {
 +      return taskFile.getTask();
 +    }
 +    return null;
 +  }
  
-   public static void update(Project project) {
+   public static void updateStudyToolWindow(Project project) {
      final StudyToolWindow studyToolWindow = getStudyToolWindow(project);
      if (studyToolWindow != null) {
        String taskText = getTaskText(project);
 -      studyToolWindow.setTaskText(taskText, null, project);
 +      if (taskText != null) {
-         studyToolWindow.setTaskText(taskText);
++        studyToolWindow.setTaskText(taskText, null, project);
 +      }
 +      else {
 +        LOG.warn("Task text is null");
 +      }
      }
    }
  
      return StudyTaskManager.getInstance(project).getCourse() != null;
    }
  
 +  @Nullable
 +  public static Project getStudyProject() {
 +    Project studyProject = null;
 +    Project[] openProjects = ProjectManager.getInstance().getOpenProjects();
 +    for (Project project : openProjects) {
 +      if (StudyTaskManager.getInstance(project).getCourse() != null) {
 +         studyProject = project;
 +      }
 +    }
 +    return studyProject;
 +  }
 +
 +  @NotNull
 +  public static File getCourseDirectory(@NotNull Project project, Course course) {
 +    final File courseDirectory;
 +    if (course.isAdaptive()) {
 +      courseDirectory = new File(StudyProjectGenerator.OUR_COURSES_DIR,
 +                                 StudyProjectGenerator.ADAPTIVE_COURSE_PREFIX + course.getName()
 +                                 + "_" + StudyTaskManager.getInstance(project).getUser().getEmail());
 +    }
 +    else {
 +      courseDirectory = new File(StudyProjectGenerator.OUR_COURSES_DIR, course.getName());
 +    }
 +    return courseDirectory;
 +  }
++
+   public static boolean hasJavaFx() {
+     try {
+       Class.forName("javafx.application.Platform");
+       return true;
+     }
+     catch (ClassNotFoundException e) {
+       return false;
+     }
+   }
+   @Nullable
+   public static Task getTask(@NotNull Project project, @NotNull VirtualFile taskVF) {
+     Course course = StudyTaskManager.getInstance(project).getCourse();
+     if (course == null) {
+       return null;
+     }
+     VirtualFile lessonVF = taskVF.getParent();
+     if (lessonVF == null) {
+       return null;
+     }
+     Lesson lesson = course.getLesson(lessonVF.getName());
+     if (lesson == null) {
+       return null;
+     }
+     return lesson.getTask(taskVF.getName());
+   }
+   @Nullable
+   public static VirtualFile getTaskDir(@NotNull VirtualFile taskFile) {
+     VirtualFile parent = taskFile.getParent();
+     if (parent == null) {
+       return null;
+     }
+     String name = parent.getName();
+     if (name.contains(EduNames.TASK)) {
+       return parent;
+     }
+     if (EduNames.SRC.equals(name)) {
+       return parent.getParent();
+     }
+     return null;
+   }
  }
index 10433f001e3f5186b6752fb3e07f2e58d3e55737,33c626a05bcb5e191afc515167ef0d59d9378412..38f6e8f91162ca64232618f3ce0a952737ba000b
@@@ -16,14 -15,13 +16,15 @@@ import com.intellij.openapi.ui.popup.Ba
  import com.intellij.openapi.ui.popup.JBPopupFactory;
  import com.intellij.openapi.util.Pair;
  import com.intellij.openapi.vfs.VirtualFile;
 -import com.intellij.openapi.wm.IdeFocusManager;
 -import com.intellij.openapi.wm.IdeFrame;
 -import com.intellij.openapi.wm.WindowManager;
 +import com.intellij.openapi.wm.*;
  import com.intellij.openapi.wm.ex.StatusBarEx;
  import com.intellij.openapi.wm.ex.WindowManagerEx;
 +import com.intellij.ui.content.Content;
 +import com.jetbrains.edu.learning.StudyState;
 +import com.jetbrains.edu.learning.StudyTaskManager;
 +import com.jetbrains.edu.learning.StudyUtils;
  import com.jetbrains.edu.learning.core.EduDocumentListener;
+ import com.jetbrains.edu.learning.core.EduNames;
  import com.jetbrains.edu.learning.core.EduUtils;
  import com.jetbrains.edu.learning.courseFormat.AnswerPlaceholder;
  import com.jetbrains.edu.learning.courseFormat.Task;
index 93a14fd9c0450e2653dda771cd4247ab1561f3dc,e643d9470cc9915c94db4d743164d10364420b7f..6132952a8274868c1110bde29f180a0275a5ca68
@@@ -24,14 -24,14 +24,19 @@@ public class Course 
    private boolean myUpToDate;
  
    @Expose @SerializedName("language")
-   private String myLanguage="Python";
+   private String myLanguage = "Python";
  
-   private String courseType="PyCharm";
+   //this field is used to distinguish ordinary and CheckIO projects
+   //"PyCharm" is used here for historical reasons
+   private String courseType = EduNames.PYCHARM;
+   //this field is used to distinguish study and course creator modes
+   private String courseMode = EduNames.STUDY;
 +  
 +  @Expose private boolean isAdaptive;
 +  
 +  @Expose
 +  private int id;
  
    /**
     * Initializes state of course
      this.courseType = courseType;
    }
  
 +  public boolean isAdaptive() {
 +    return isAdaptive;
 +  }
 +
 +  public void setAdaptive(boolean adaptive) {
 +    isAdaptive = adaptive;
 +  }
 +
 +  public int getId() {
 +    return id;
 +  }
 +
 +  public void setId(int id) {
 +    this.id = id;
 +  }
++
+   public String getCourseMode() {
+     return courseMode;
+   }
+   public void setCourseMode(String courseMode) {
+     this.courseMode = courseMode;
+   }
  }
index a1f20ef32283a29b4f4a6d77cdf1d48f48d0debc,058bd633a29b342aca10117dda6e2a7f68c68319..d9507f11164f29316c52fae67eb4ed7f6c0cea5b
@@@ -41,8 -39,8 +40,8 @@@ public class StudyJavaFxToolWindow exte
    }
  
    @Override
-   public void setTaskText(@NotNull String text) {
 -  public void setText(String text) {
++  public void setText(@NotNull String text) {
      StudyPluginConfigurator configurator = StudyUtils.getConfigurator(ProjectUtil.guessCurrentProject(this));
 -      myBrowserWindow.loadContent(text, configurator);
 +    myBrowserWindow.loadContent(text, configurator);
    }
  }
index 2c8ee7708bb1d00433367302cb78ea7150ce7683,89fa41319b72d76455240b62a99cb418af27b6e6..89ef2ae07938614451ea8bb3f3e2c2d4dc29c971
@@@ -3,12 -3,10 +3,14 @@@ package com.jetbrains.edu.learning.ui
  import com.intellij.facet.ui.FacetValidatorsManager;
  import com.intellij.facet.ui.ValidationResult;
  import com.intellij.icons.AllIcons;
 +import com.intellij.openapi.application.ApplicationManager;
 +import com.intellij.openapi.diagnostic.Logger;
  import com.intellij.openapi.fileChooser.FileChooser;
  import com.intellij.openapi.fileChooser.FileChooserDescriptor;
 +import com.intellij.openapi.progress.ProgressManager;
 +import com.intellij.openapi.project.DefaultProjectFactoryImpl;
+ import com.intellij.openapi.project.Project;
+ import com.intellij.openapi.project.ProjectManager;
  import com.intellij.openapi.ui.DialogWrapper;
  import com.intellij.openapi.ui.popup.JBPopupFactory;
  import com.intellij.openapi.ui.popup.ListPopup;
@@@ -17,8 -15,8 +19,8 @@@ import com.intellij.openapi.ui.popup.ut
  import com.intellij.openapi.util.text.StringUtil;
  import com.intellij.openapi.vfs.VirtualFile;
  import com.intellij.util.Consumer;
--import com.jetbrains.edu.learning.StudyUtils;
  import com.jetbrains.edu.learning.courseFormat.Course;
++import com.jetbrains.edu.learning.StudyUtils;
  import com.jetbrains.edu.learning.courseGeneration.StudyProjectGenerator;
  import com.jetbrains.edu.learning.stepic.CourseInfo;
  import com.jetbrains.edu.learning.stepic.EduStepicConnector;
index 3e88467cf9a42f4664b7c968f18fedbadc0c3421,ebaff662ecb84db332586cf2249bc620478cdc3f..be13a1b0f46d08ce753012685bd627e2cd7c749c
@@@ -19,8 -20,8 +20,9 @@@ import com.intellij.openapi.editor.colo
  import com.intellij.openapi.project.Project;
  import com.intellij.ui.BrowserHyperlinkListener;
  import com.intellij.ui.ColorUtil;
+ import com.intellij.ui.components.JBScrollPane;
  import com.intellij.util.ui.UIUtil;
 +import org.jetbrains.annotations.NotNull;
  
  import javax.swing.*;
  import javax.swing.border.EmptyBorder;
@@@ -54,13 -56,12 +57,12 @@@ public class StudySwingToolWindow exten
      if (!UIUtil.isUnderDarcula()) {
        myTaskTextPane.setBackground(EditorColorsManager.getInstance().getGlobalScheme().getDefaultBackground());
      }
-     myTaskTextPane.setBorder(new EmptyBorder(15, 20, 0, 100));
-     myTaskTextPane.setText(taskText);
+     myTaskTextPane.setBorder(new EmptyBorder(20, 20, 0, 10));
      myTaskTextPane.addHyperlinkListener(BrowserHyperlinkListener.INSTANCE);
-     return myTaskTextPane;
+     return scrollPane;
    }
  
-   public void setTaskText(@NotNull String text) {
 -  public void setText(String text) {
++  public void setText(@NotNull String text) {
      myTaskTextPane.setText(text);
    }
  }
index a6bcb056660a8b6288401d9d76610a12175e1d4e,feb06b72159a898193fa3b6b1f490c96e8eb4027..589d0179f6ad289ddf3f273839f4c6c1e1cc6a93
   */
  package com.jetbrains.edu.learning.ui;
  
+ import com.intellij.ide.browsers.WebBrowserManager;
  import com.intellij.openapi.Disposable;
- import com.intellij.openapi.actionSystem.ActionManager;
- import com.intellij.openapi.actionSystem.ActionToolbar;
- import com.intellij.openapi.actionSystem.DataProvider;
- import com.intellij.openapi.actionSystem.DefaultActionGroup;
+ import com.intellij.openapi.actionSystem.*;
  import com.intellij.openapi.diagnostic.Logger;
+ import com.intellij.openapi.editor.Document;
+ import com.intellij.openapi.editor.EditorFactory;
+ import com.intellij.openapi.editor.ex.EditorEx;
+ import com.intellij.openapi.extensions.Extensions;
+ import com.intellij.openapi.fileEditor.FileDocumentManager;
  import com.intellij.openapi.fileEditor.FileEditorManagerListener;
 +import com.intellij.openapi.progress.ProgressIndicator;
 +import com.intellij.openapi.progress.ProgressManager;
 +import com.intellij.openapi.progress.Task;
 +import com.intellij.openapi.progress.util.ProgressIndicatorBase;
  import com.intellij.openapi.project.Project;
 +import com.intellij.openapi.project.ProjectUtil;
  import com.intellij.openapi.ui.SimpleToolWindowPanel;
+ import com.intellij.openapi.util.Disposer;
+ import com.intellij.openapi.vfs.VirtualFile;
  import com.intellij.ui.JBCardLayout;
 +import com.intellij.ui.JBColor;
  import com.intellij.ui.OnePixelSplitter;
  import com.intellij.util.ui.JBUI;
- import com.intellij.util.ui.UIUtil;
- import com.jetbrains.edu.learning.StudyBasePluginConfigurator;
- import com.jetbrains.edu.learning.StudyPluginConfigurator;
- import com.jetbrains.edu.learning.StudyTaskManager;
- import com.jetbrains.edu.learning.StudyUtils;
+ import com.jetbrains.edu.learning.*;
+ import com.jetbrains.edu.learning.core.EduNames;
  import com.jetbrains.edu.learning.courseFormat.Course;
 +import com.jetbrains.edu.learning.stepic.EduAdaptiveStepicConnector;
+ import com.jetbrains.edu.learning.courseFormat.TaskFile;
  import org.jetbrains.annotations.NotNull;
  
  import javax.swing.*;
@@@ -66,17 -61,10 +70,17 @@@ public abstract class StudyToolWindow e
      String taskText = StudyUtils.getTaskText(project);
      if (taskText == null) return;
  
-     JPanel toolbarPanel = createToolbarPanel(project);
+     JPanel toolbarPanel = createToolbarPanel(getActionGroup(project));
      setToolbar(toolbarPanel);
--
 -    myContentPanel.add(TASK_INFO_ID, createTaskInfoPanel(project));
++    
 +    final JPanel panel = new JPanel(new BorderLayout());
 +    final Course course = StudyTaskManager.getInstance(project).getCourse();
 +    if (course != null && course.isAdaptive()) {
 +      panel.add(createReactionPanel(), BorderLayout.NORTH);
 +    }
 +    JComponent taskInfoPanel = createTaskInfoPanel(taskText, project);
 +    panel.add(taskInfoPanel, BorderLayout.CENTER);
 +    myContentPanel.add(TASK_INFO_ID, panel);
      mySplitPane.setFirstComponent(myContentPanel);
      addAdditionalPanels(project);
      myCardLayout.show(myContentPanel, TASK_INFO_ID);
        }
      }
    }
 +  
 +  public JPanel createReactionPanel() {
 +    final JPanel panel = new JPanel(new GridBagLayout());
 +    panel.setBorder(BorderFactory.createMatteBorder(0, 0, 1, 0, JBColor.border()));
 +    final JPanel hardPanel = new JPanel(new BorderLayout());
 +    hardPanel.add(new JLabel("Too hard"), BorderLayout.CENTER);
 +    hardPanel.setBorder(BorderFactory.createEtchedBorder());
 +
 +    final JPanel boringPanel = new JPanel(new BorderLayout());
 +    boringPanel.setBorder(BorderFactory.createEtchedBorder());
 +    boringPanel.add(new JLabel("Too boring"), BorderLayout.CENTER);
 +
 +    final GridBagConstraints c = new GridBagConstraints();
 +    c.fill  = GridBagConstraints.HORIZONTAL;
 +    c.gridx = 0;
 +    c.gridy = 0;
 +    c.weightx = 1;
 +    panel.add(hardPanel, c);
 +    c.gridx =  1;
 +    panel.add(boringPanel, c);
 +    c.gridy = 1;
 +    c.weightx = 1;
 +    panel.add(Box.createVerticalBox(), c);
 +
 +    final Project project = ProjectUtil.guessCurrentProject(myContentPanel);
 +    addMouseListener(hardPanel, () -> EduAdaptiveStepicConnector.addNextRecommendedTask(project, 0));
 +    addMouseListener(boringPanel, () -> EduAdaptiveStepicConnector.addNextRecommendedTask(project, -1));
 +    
 +    return panel;
 +  }
 +
 +  private static void addMouseListener(@NotNull final JPanel panel, @NotNull Runnable onClickAction ) {
 +    panel.addMouseListener(new MouseAdapter() {
 +      @Override
 +      public void mouseClicked(MouseEvent e) {
 +        if (e.getClickCount() == 1) {
 +          final ProgressIndicatorBase progress = new ProgressIndicatorBase();
 +          progress.setText("Loading Next Recommendation");
 +          ProgressManager.getInstance().run(new Task.Backgroundable(ProjectUtil.guessCurrentProject(panel),
 +                                                                    "Loading Next Recommendation") {
  
 +            @Override
 +            public void run(@NotNull ProgressIndicator indicator) {
 +              onClickAction.run();
 +            }
 +          });
 +        }
 +      }
 +
 +      @Override
 +      public void mouseEntered(MouseEvent e) {
 +        panel.setBackground(UIUtil.getTreeSelectionBackground());
 +      }
 +
 +      @Override
 +      public void mouseExited(MouseEvent e) {
 +        panel.setBackground(UIUtil.getLabelBackground());
 +      }
 +    });
 +  }
 +  
    public void dispose() {
    }
-   
    //used in checkiO plugin.
    @SuppressWarnings("unused")
    public void showPanelById(@NotNull final String panelId) {
      }
    }
  
-   public abstract void setTaskText(@NotNull String text);
+   private static void addAdditionalActions(DefaultActionGroup group) {
+     StudyActionsProvider[] providers = Extensions.getExtensions(StudyActionsProvider.EP_NAME);
+     for (StudyActionsProvider provider : providers) {
+       group.addAll(provider.getActions());
+     }
+   }
+   public void setTaskText(String text, VirtualFile taskDirectory, Project project) {
+     if (StudyTaskManager.getInstance(project).isTurnEditingMode()) {
+       if (taskDirectory == null) {
+         LOG.info("Failed to enter editing mode for StudyToolWindow");
+         return;
+       }
+       VirtualFile taskTextFile = taskDirectory.findChild(EduNames.TASK_HTML);
+       enterEditingMode(taskTextFile, project);
+       StudyTaskManager.getInstance(project).setTurnEditingMode(false);
+     }
+     else {
+       setText(text);
+     }
+   }
 -  protected abstract void setText(String text);
++  protected abstract void setText(@NotNull String text);
+   public void setEmptyText(@NotNull Project project) {
+     if (StudyTaskManager.getInstance(project).getToolWindowMode() == StudyToolWindowMode.EDITING) {
+       mySplitPane.setFirstComponent(myContentPanel);
+       StudyTaskManager.getInstance(project).setTurnEditingMode(true);
+     }
+     setTaskText(EMPTY_TASK_TEXT, null, project);
+   }
+   public enum StudyToolWindowMode {
+     TEXT, EDITING
+   }
+   public void enterEditingMode(VirtualFile taskFile, Project project) {
+     final EditorFactory factory = EditorFactory.getInstance();
+     Document document = FileDocumentManager.getInstance().getDocument(taskFile);
+     if (document == null) {
+       return;
+     }
+     WebBrowserManager.getInstance().setShowBrowserHover(false);
+     final EditorEx createdEditor = (EditorEx)factory.createEditor(document, project, taskFile, false);
+     Disposer.register(project, new Disposable() {
+       public void dispose() {
+         factory.releaseEditor(createdEditor);
+       }
+     });
+     JComponent editorComponent = createdEditor.getComponent();
+     mySplitPane.setFirstComponent(editorComponent);
+     mySplitPane.repaint();
+     StudyTaskManager.getInstance(project).setToolWindowMode(StudyToolWindowMode.EDITING);
+   }
+   public void leaveEditingMode(Project project) {
+     WebBrowserManager.getInstance().setShowBrowserHover(true);
+     mySplitPane.setFirstComponent(myContentPanel);
+     StudyTaskManager.getInstance(project).setToolWindowMode(StudyToolWindowMode.TEXT);
+     StudyUtils.updateStudyToolWindow(project);
+   }
  }
index 23385fd077ce2f23a8a50add9758cfe4cea5c481,886936b22112b30acf01b793c6b66868bd2c3aad..4530e004504dc042433ff1c05e2c1ec6ccb71f4f
@@@ -7,8 -7,8 +7,9 @@@ import com.intellij.openapi.wm.ToolWind
  import com.intellij.openapi.wm.ToolWindowFactory;
  import com.intellij.ui.content.Content;
  import com.intellij.ui.content.ContentManager;
 +import com.jetbrains.edu.learning.StudyProjectComponent;
  import com.jetbrains.edu.learning.StudyTaskManager;
+ import com.jetbrains.edu.learning.StudyUtils;
  import com.jetbrains.edu.learning.courseFormat.Course;
  import icons.InteractiveLearningIcons;
  import org.jetbrains.annotations.NotNull;
@@@ -23,8 -23,9 +24,8 @@@ public class StudyToolWindowFactory imp
      StudyTaskManager taskManager = StudyTaskManager.getInstance(project);
      final Course course = taskManager.getCourse();
      if (course != null) {
 -
        final StudyToolWindow studyToolWindow;
-       if (StudyProjectComponent.getInstance(project).useJavaFx()) {
+       if (StudyUtils.hasJavaFx() && StudyTaskManager.getInstance(project).shouldUseJavaFx()) {
          studyToolWindow = new StudyJavaFxToolWindow();
        }
        else {
index c25ee848ee7b507712b7dcc17fbb2eed79010139,80c21a26244ec50c3d06319bc5cf8fe01ae641fe..0758b722ce7cd9d1e561d9e3bb1988276414bea8
@@@ -21,7 -21,6 +21,8 @@@
          <SOURCES />
        </library>
      </orderEntry>
 +    <orderEntry type="module" module-name="platform-api" />
 +    <orderEntry type="module" module-name="python-community" />
+     <orderEntry type="module" module-name="xml" />
    </component>
  </module>
index d8e4f3df2f2eafa3294fdfe9cbd504f19322281c,fdb110718b3401f5a580a6754481228f6e825a88..0f5ab396df3f5f5e01c5bc20ae3ca12ed7707afd
@@@ -14,7 -15,8 +14,9 @@@ import com.jetbrains.edu.learning.actio
  import com.jetbrains.edu.learning.checker.StudyCheckTask;
  import com.jetbrains.edu.learning.checker.StudyCheckUtils;
  import com.jetbrains.edu.learning.checker.StudyTestRunner;
+ import com.jetbrains.edu.learning.checker.StudyTestsOutputParser;
+ import com.jetbrains.edu.learning.core.EduNames;
 +import com.jetbrains.edu.learning.courseFormat.Course;
  import com.jetbrains.edu.learning.courseFormat.StudyStatus;
  import com.jetbrains.edu.learning.courseFormat.Task;
  import com.jetbrains.edu.learning.courseFormat.TaskFile;
@@@ -91,30 -92,29 +93,32 @@@ public class PyStudyCheckAction extend
                                        final Process testProcess,
                                        final String commandLine) {
      return new StudyCheckTask(project, studyState, myCheckInProgress, testProcess, commandLine) {
 -            @Override
 -            protected void onTaskFailed(StudyTestsOutputParser.TestsOutput testsOutput) {
 -              ApplicationManager.getApplication().invokeLater(() -> {
 -                if (myTaskDir == null) return;
 -                myTaskManger.setStatus(myTask, StudyStatus.Failed);
 -                for (Map.Entry<String, TaskFile> entry : myTask.getTaskFiles().entrySet()) {
 -                  final String name = entry.getKey();
 -                  final TaskFile taskFile = entry.getValue();
 -                  if (taskFile.getAnswerPlaceholders().size() < 2) {
 -                    myTaskManger.setStatus(taskFile, StudyStatus.Failed);
 -                    continue;
 -                  }
 -                  if (EduNames.STUDY.equals(myTaskManger.getCourse().getCourseMode())) {
 -                    CommandProcessor.getInstance().runUndoTransparentAction(() -> ApplicationManager.getApplication().runWriteAction(() -> {
 -                      StudyCheckUtils.runSmartTestProcess(myTaskDir, testRunner, name, taskFile, project);
 -                    }));
 -                  }
 -                }
 -                StudyCheckUtils.showTestResultPopUp(testsOutput.getMessage(), MessageType.ERROR.getPopupBackground(), project);
 -                StudyCheckUtils.navigateToFailedPlaceholder(myStudyState, myTask, myTaskDir, project);
 -              });
 +      @Override
 +      protected void onTaskFailed(String message) {
 +        ApplicationManager.getApplication().invokeLater(() -> {
 +          if (myTaskDir == null) return;
 +          myTaskManger.setStatus(myTask, StudyStatus.Failed);
 +          for (Map.Entry<String, TaskFile> entry : myTask.getTaskFiles().entrySet()) {
 +            final String name = entry.getKey();
 +            final TaskFile taskFile = entry.getValue();
 +            if (taskFile.getAnswerPlaceholders().size() < 2) {
 +              myTaskManger.setStatus(taskFile, StudyStatus.Failed);
 +              continue;
 +            }
-             CommandProcessor.getInstance().runUndoTransparentAction(() -> ApplicationManager.getApplication().runWriteAction(() -> {
-               StudyCheckUtils.runSmartTestProcess(myTaskDir, testRunner, name, taskFile, project);
-             }));
++            if (EduNames.STUDY.equals(myTaskManger.getCourse().getCourseMode())) {
++              CommandProcessor.getInstance().runUndoTransparentAction(() -> ApplicationManager.getApplication().runWriteAction(() -> {
++                StudyCheckUtils.runSmartTestProcess(myTaskDir, testRunner, name, taskFile, project);
++              }));
+             }
 -          };
 +          }
 +          final StudyToolWindow toolWindow = StudyUtils.getStudyToolWindow(project);
 +          if (toolWindow != null) {
 +            StudyCheckUtils.showTestResults(project, message, false);
 +            StudyCheckUtils.navigateToFailedPlaceholder(myStudyState, myTask, myTaskDir, project);
 +          }
 +        });
 +      }
 +    };
    }