summaryrefslogtreecommitdiff
path: root/python/edu/learn-python/src/com/jetbrains/python/edu/ui
diff options
context:
space:
mode:
Diffstat (limited to 'python/edu/learn-python/src/com/jetbrains/python/edu/ui')
-rw-r--r--python/edu/learn-python/src/com/jetbrains/python/edu/ui/StudyCondition.java25
-rw-r--r--python/edu/learn-python/src/com/jetbrains/python/edu/ui/StudyNewProjectPanel.form84
-rw-r--r--python/edu/learn-python/src/com/jetbrains/python/edu/ui/StudyNewProjectPanel.java196
-rw-r--r--python/edu/learn-python/src/com/jetbrains/python/edu/ui/StudyProgressBar.java92
-rw-r--r--python/edu/learn-python/src/com/jetbrains/python/edu/ui/StudyTestContentPanel.java67
-rw-r--r--python/edu/learn-python/src/com/jetbrains/python/edu/ui/StudyToolWindowFactory.java81
6 files changed, 545 insertions, 0 deletions
diff --git a/python/edu/learn-python/src/com/jetbrains/python/edu/ui/StudyCondition.java b/python/edu/learn-python/src/com/jetbrains/python/edu/ui/StudyCondition.java
new file mode 100644
index 000000000000..5add6c934ecd
--- /dev/null
+++ b/python/edu/learn-python/src/com/jetbrains/python/edu/ui/StudyCondition.java
@@ -0,0 +1,25 @@
+package com.jetbrains.python.edu.ui;
+
+import com.intellij.openapi.project.DumbAware;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Condition;
+import com.jetbrains.python.edu.StudyTaskManager;
+
+/**
+ * author: liana
+ * data: 7/29/14.
+ */
+public class StudyCondition implements Condition, DumbAware {
+ public static boolean VALUE = false;
+ @Override
+ public boolean value(Object o) {
+ if (o instanceof Project) {
+ Project project = (Project) o;
+ StudyTaskManager taskManager = StudyTaskManager.getInstance(project);
+ if (taskManager.getCourse() != null) {
+ VALUE = true;
+ }
+ }
+ return false;
+ }
+}
diff --git a/python/edu/learn-python/src/com/jetbrains/python/edu/ui/StudyNewProjectPanel.form b/python/edu/learn-python/src/com/jetbrains/python/edu/ui/StudyNewProjectPanel.form
new file mode 100644
index 000000000000..133c38d4e8f8
--- /dev/null
+++ b/python/edu/learn-python/src/com/jetbrains/python/edu/ui/StudyNewProjectPanel.form
@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.jetbrains.python.edu.ui.StudyNewProjectPanel">
+ <grid id="27dc6" binding="myContentPanel" layout-manager="GridLayoutManager" row-count="2" 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="500" height="400"/>
+ </constraints>
+ <properties/>
+ <border type="none"/>
+ <children>
+ <grid id="54488" layout-manager="GridLayoutManager" row-count="2" 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="1" column="1" row-span="1" col-span="3" vsize-policy="2" hsize-policy="4" anchor="0" fill="3" indent="0" use-parent-layout="false">
+ <minimum-size width="-1" height="60"/>
+ <preferred-size width="-1" height="60"/>
+ </grid>
+ </constraints>
+ <properties/>
+ <border type="line">
+ <color color="-6709600"/>
+ </border>
+ <children>
+ <component id="213f6" class="javax.swing.JLabel" binding="myAuthorLabel">
+ <constraints>
+ <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties>
+ <text value=""/>
+ </properties>
+ </component>
+ <component id="d754d" class="javax.swing.JLabel" binding="myDescriptionLabel">
+ <constraints>
+ <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties>
+ <text value=""/>
+ </properties>
+ </component>
+ </children>
+ </grid>
+ <component id="6c40c" class="javax.swing.JLabel">
+ <constraints>
+ <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="1" indent="0" use-parent-layout="false">
+ <preferred-size width="81" height="-1"/>
+ </grid>
+ </constraints>
+ <properties>
+ <font/>
+ <horizontalTextPosition value="0"/>
+ <text value="Courses:"/>
+ </properties>
+ </component>
+ <component id="21ac6" class="javax.swing.JComboBox" binding="myCoursesComboBox">
+ <constraints>
+ <grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="7" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties/>
+ </component>
+ <component id="5c614" class="com.intellij.openapi.ui.FixedSizeButton" binding="myBrowseButton">
+ <constraints>
+ <grid row="0" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="1" indent="0" use-parent-layout="false">
+ <minimum-size width="30" height="25"/>
+ </grid>
+ </constraints>
+ <properties/>
+ </component>
+ <component id="f1e10" class="javax.swing.JButton" binding="myRefreshButton">
+ <constraints>
+ <grid row="0" column="3" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="1" indent="0" use-parent-layout="false">
+ <minimum-size width="30" height="23"/>
+ </grid>
+ </constraints>
+ <properties>
+ <hideActionText value="false"/>
+ <text value=""/>
+ <toolTipText value="Refresh course list"/>
+ <verticalAlignment value="1"/>
+ <verticalTextPosition value="1"/>
+ </properties>
+ </component>
+ </children>
+ </grid>
+</form>
diff --git a/python/edu/learn-python/src/com/jetbrains/python/edu/ui/StudyNewProjectPanel.java b/python/edu/learn-python/src/com/jetbrains/python/edu/ui/StudyNewProjectPanel.java
new file mode 100644
index 000000000000..0f1ec08a8856
--- /dev/null
+++ b/python/edu/learn-python/src/com/jetbrains/python/edu/ui/StudyNewProjectPanel.java
@@ -0,0 +1,196 @@
+package com.jetbrains.python.edu.ui;
+
+import com.intellij.facet.ui.FacetValidatorsManager;
+import com.intellij.facet.ui.ValidationResult;
+import com.intellij.openapi.fileChooser.FileChooser;
+import com.intellij.openapi.fileChooser.FileChooserDescriptor;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.util.Consumer;
+import com.jetbrains.python.edu.StudyDirectoryProjectGenerator;
+import com.jetbrains.python.edu.StudyUtils;
+import com.jetbrains.python.edu.course.CourseInfo;
+import icons.StudyIcons;
+
+import javax.swing.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.io.File;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * author: liana
+ * data: 7/31/14.
+ */
+public class StudyNewProjectPanel{
+ private Set<CourseInfo> myAvailableCourses = new HashSet<CourseInfo>();
+ private JComboBox myCoursesComboBox;
+ private JButton myBrowseButton;
+ private JButton myRefreshButton;
+ private JPanel myContentPanel;
+ private JLabel myAuthorLabel;
+ private JLabel myDescriptionLabel;
+ private final StudyDirectoryProjectGenerator myGenerator;
+ private static final String CONNECTION_ERROR = "<html>Failed to download courses.<br>Check your Internet connection.</html>";
+ private static final String INVALID_COURSE = "Selected course is invalid";
+ private FacetValidatorsManager myValidationManager;
+
+ public StudyNewProjectPanel(StudyDirectoryProjectGenerator generator) {
+ myGenerator = generator;
+ Map<CourseInfo, File> courses = myGenerator.getCourses();
+ if (courses.isEmpty()) {
+ setError(CONNECTION_ERROR);
+ }
+ else {
+ myAvailableCourses = courses.keySet();
+ for (CourseInfo courseInfo : myAvailableCourses) {
+ myCoursesComboBox.addItem(courseInfo);
+ }
+ myAuthorLabel.setText("Author: " + StudyUtils.getFirst(myAvailableCourses).getAuthor());
+ myDescriptionLabel.setText(StudyUtils.getFirst(myAvailableCourses).getDescription());
+ //setting the first course in list as selected
+ myGenerator.setSelectedCourse(StudyUtils.getFirst(myAvailableCourses));
+ setOK();
+ }
+ initListeners();
+ myRefreshButton.setVisible(true);
+ myRefreshButton.setIcon(StudyIcons.Refresh);
+ }
+
+ private void initListeners() {
+
+ final FileChooserDescriptor fileChooser = new FileChooserDescriptor(true, false, false, true, false, false) {
+ @Override
+ public boolean isFileVisible(VirtualFile file, boolean showHiddenFiles) {
+ return file.isDirectory() || StudyUtils.isZip(file.getName());
+ }
+
+ @Override
+ public boolean isFileSelectable(VirtualFile file) {
+ return StudyUtils.isZip(file.getName());
+ }
+ };
+ myBrowseButton.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ FileChooser.chooseFile(fileChooser, null, null,
+ new Consumer<VirtualFile>() {
+ @Override
+ public void consume(VirtualFile file) {
+ String fileName = file.getPath();
+ int oldSize = myAvailableCourses.size();
+ CourseInfo courseInfo = myGenerator.addLocalCourse(fileName);
+ if (courseInfo != null) {
+ if (oldSize != myAvailableCourses.size()) {
+ myCoursesComboBox.addItem(courseInfo);
+ }
+ myCoursesComboBox.setSelectedItem(courseInfo);
+ setOK();
+ }
+ else {
+ setError(INVALID_COURSE);
+ myCoursesComboBox.removeAllItems();
+ myCoursesComboBox.addItem(CourseInfo.INVALID_COURSE);
+ for (CourseInfo course : myAvailableCourses) {
+ myCoursesComboBox.addItem(course);
+ }
+ myCoursesComboBox.setSelectedItem(CourseInfo.INVALID_COURSE);
+ }
+ }
+ });
+ }
+ });
+ myRefreshButton.addActionListener(new RefreshActionListener());
+ myCoursesComboBox.addActionListener(new CourseSelectedListener());
+ }
+
+ private void setError(String errorMessage) {
+ myGenerator.setValidationResult(new ValidationResult(errorMessage));
+ if (myValidationManager != null) {
+ myValidationManager.validate();
+ }
+ }
+
+ private void setOK() {
+ myGenerator.setValidationResult(ValidationResult.OK);
+ if (myValidationManager != null) {
+ myValidationManager.validate();
+ }
+ }
+
+ public JPanel getContentPanel() {
+ return myContentPanel;
+ }
+
+ public void registerValidators(final FacetValidatorsManager manager) {
+ myValidationManager = manager;
+ }
+
+
+ /**
+ * Handles refreshing courses
+ * Old courses added to new courses only if their
+ * meta file still exists in local file system
+ */
+ private class RefreshActionListener implements ActionListener {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ myGenerator.downloadAndUnzip(true);
+ Map<CourseInfo, File> downloadedCourses = myGenerator.loadCourses();
+ if (downloadedCourses.isEmpty()) {
+ setError(CONNECTION_ERROR);
+ return;
+ }
+ Map<CourseInfo, File> oldCourses = myGenerator.getLoadedCourses();
+ Map<CourseInfo, File> newCourses = new HashMap<CourseInfo, File>();
+ for (Map.Entry<CourseInfo, File> course : oldCourses.entrySet()) {
+ File courseFile = course.getValue();
+ if (courseFile.exists()) {
+ newCourses.put(course.getKey(), courseFile);
+ }
+ }
+ for (Map.Entry<CourseInfo, File> course : downloadedCourses.entrySet()) {
+ CourseInfo courseName = course.getKey();
+ if (newCourses.get(courseName) == null) {
+ newCourses.put(courseName, course.getValue());
+ }
+ }
+ myCoursesComboBox.removeAllItems();
+
+ for (CourseInfo courseInfo : newCourses.keySet()) {
+ myCoursesComboBox.addItem(courseInfo);
+ }
+ myGenerator.setSelectedCourse(StudyUtils.getFirst(newCourses.keySet()));
+
+ myGenerator.setCourses(newCourses);
+ myAvailableCourses = newCourses.keySet();
+ myGenerator.flushCache();
+ }
+ }
+
+
+ /**
+ * Handles selecting course in combo box
+ * Sets selected course in combo box as selected in
+ * {@link StudyNewProjectPanel#myGenerator}
+ */
+ private class CourseSelectedListener implements ActionListener {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ JComboBox cb = (JComboBox)e.getSource();
+ CourseInfo selectedCourse = (CourseInfo)cb.getSelectedItem();
+ if (selectedCourse == null || selectedCourse.equals(CourseInfo.INVALID_COURSE)) {
+ myAuthorLabel.setText("");
+ myDescriptionLabel.setText("");
+ return;
+ }
+ myAuthorLabel.setText("Author: " + selectedCourse.getAuthor());
+ myCoursesComboBox.removeItem(CourseInfo.INVALID_COURSE);
+ myDescriptionLabel.setText(selectedCourse.getDescription());
+ myGenerator.setSelectedCourse(selectedCourse);
+ setOK();
+ }
+ }
+}
diff --git a/python/edu/learn-python/src/com/jetbrains/python/edu/ui/StudyProgressBar.java b/python/edu/learn-python/src/com/jetbrains/python/edu/ui/StudyProgressBar.java
new file mode 100644
index 000000000000..97fa00d0f70d
--- /dev/null
+++ b/python/edu/learn-python/src/com/jetbrains/python/edu/ui/StudyProgressBar.java
@@ -0,0 +1,92 @@
+package com.jetbrains.python.edu.ui;
+
+import com.intellij.openapi.project.DumbAware;
+import com.intellij.openapi.ui.GraphicsConfig;
+import com.intellij.ui.ColorUtil;
+import com.intellij.ui.Gray;
+import com.intellij.ui.JBColor;
+import com.intellij.util.ui.GraphicsUtil;
+import com.intellij.util.ui.UIUtil;
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.geom.Rectangle2D;
+
+public class StudyProgressBar extends JComponent implements DumbAware {
+ public static final Color BLUE = JBColor.BLUE;
+ private static final Color SHADOW1 = new JBColor(Gray._190, JBColor.border());
+ private static final Color SHADOW2 = Gray._105;
+ private static final int BRICK_WIDTH = 10;
+ private static final int BRICK_SPACE = 2;
+ private final int myHeight;
+ private final int myIndent;
+ private double myFraction = 0.0;
+ private Color myColor = BLUE;
+
+ public StudyProgressBar(double fraction, Color color, int height, int indent) {
+ myFraction = fraction;
+ myColor = color;
+ myHeight = height;
+ myIndent = indent;
+ }
+
+ private int getBricksToDraw(double fraction) {
+ int bricksTotal = (getWidth() - 8) / (BRICK_WIDTH + BRICK_SPACE);
+ return (int)(bricksTotal * fraction) + 1;
+ }
+
+ protected void paintComponent(Graphics g) {
+ final GraphicsConfig config = GraphicsUtil.setupAAPainting(g);
+ Graphics2D g2 = (Graphics2D)g;
+ if (myFraction > 1) {
+ myFraction = 1;
+ }
+
+ Dimension size = getSize();
+ double width = size.getWidth() - 2*myIndent;
+ g2.setPaint(UIUtil.getListBackground());
+ Rectangle2D rect = new Rectangle2D.Double(myIndent, 0, width, myHeight);
+ g2.fill(rect);
+
+ g2.setPaint(new JBColor(SHADOW1, JBColor.border()));
+ rect.setRect(myIndent, 0, width, myHeight);
+ int arcWidth = 5;
+ int arcHeight = 5;
+ g2.drawRoundRect(myIndent, 0, (int)width, myHeight, arcWidth, arcHeight);
+ g2.setPaint(SHADOW2);
+ g2.drawRoundRect(myIndent, 0, (int)width, myHeight, arcWidth, arcHeight);
+
+ int y_center = myHeight / 2;
+ int y_steps = myHeight / 2 - 3;
+ int alpha_step = y_steps > 0 ? (255 - 70) / y_steps : 255 - 70;
+ int x_offset = 4;
+
+ g.setClip(4 + myIndent, 3, (int)width - 6, myHeight - 4);
+
+ int bricksToDraw = myFraction == 0 ? 0 : getBricksToDraw(myFraction);
+ for (int i = 0; i < bricksToDraw; i++) {
+ g2.setPaint(myColor);
+ UIUtil.drawLine(g2, x_offset, y_center, x_offset + BRICK_WIDTH - 1, y_center);
+ for (int j = 0; j < y_steps; j++) {
+ Color color = ColorUtil.toAlpha(myColor, 255 - alpha_step * (j + 1));
+ g2.setPaint(color);
+ UIUtil.drawLine(g2, x_offset, y_center - 1 - j, x_offset + BRICK_WIDTH - 1, y_center - 1 - j);
+ if (!(y_center % 2 != 0 && j == y_steps - 1)) {
+ UIUtil.drawLine(g2, x_offset, y_center + 1 + j, x_offset + BRICK_WIDTH - 1, y_center + 1 + j);
+ }
+ }
+ g2.setColor(
+ ColorUtil.toAlpha(myColor, 255 - alpha_step * (y_steps / 2 + 1)));
+ g2.drawRect(x_offset, y_center - y_steps, BRICK_WIDTH - 1, myHeight - 7);
+ x_offset += BRICK_WIDTH + BRICK_SPACE;
+ }
+ config.restore();
+ }
+
+ @Override
+ public Dimension getMaximumSize() {
+ Dimension dimension = super.getMaximumSize();
+ dimension.height = myHeight + 10;
+ return dimension;
+ }
+}
diff --git a/python/edu/learn-python/src/com/jetbrains/python/edu/ui/StudyTestContentPanel.java b/python/edu/learn-python/src/com/jetbrains/python/edu/ui/StudyTestContentPanel.java
new file mode 100644
index 000000000000..dee4fbaf9d01
--- /dev/null
+++ b/python/edu/learn-python/src/com/jetbrains/python/edu/ui/StudyTestContentPanel.java
@@ -0,0 +1,67 @@
+package com.jetbrains.python.edu.ui;
+
+import com.intellij.ui.DocumentAdapter;
+import com.intellij.ui.components.JBScrollPane;
+import org.jetbrains.annotations.NotNull;
+import com.jetbrains.python.edu.course.UserTest;
+
+import javax.swing.*;
+import javax.swing.event.DocumentEvent;
+import javax.swing.text.BadLocationException;
+import java.awt.*;
+
+public class StudyTestContentPanel extends JPanel {
+ public static final Dimension PREFERRED_SIZE = new Dimension(300, 200);
+ private static final Font HEADER_FONT = new Font("Arial", Font.BOLD, 16);
+ private final JTextArea myInputArea = new JTextArea();
+ private final JTextArea myOutputArea = new JTextArea();
+ public StudyTestContentPanel(UserTest userTest) {
+ this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
+ initContentLabel("input", myInputArea);
+ myInputArea.getDocument().addDocumentListener(new BufferUpdater(userTest.getInputBuffer()));
+ myOutputArea.getDocument().addDocumentListener(new BufferUpdater(userTest.getOutputBuffer()));
+ initContentLabel("output", myOutputArea);
+ setEditable(userTest.isEditable());
+ }
+
+ private void initContentLabel(final String headerText, @NotNull final JTextArea contentArea) {
+ JLabel headerLabel = new JLabel(headerText);
+ headerLabel.setFont(HEADER_FONT);
+ this.add(headerLabel);
+ this.add(new JSeparator(SwingConstants.HORIZONTAL));
+ JScrollPane scroll = new JBScrollPane(contentArea);
+ scroll.setPreferredSize(PREFERRED_SIZE);
+ this.add(scroll);
+ }
+
+ private void setEditable(boolean isEditable) {
+ myInputArea.setEditable(isEditable);
+ myOutputArea.setEditable(isEditable);
+ }
+ public void addInputContent(final String content) {
+ myInputArea.setText(content);
+ }
+
+ public void addOutputContent(final String content) {
+ myOutputArea.setText(content);
+ }
+
+ private class BufferUpdater extends DocumentAdapter {
+ private final StringBuilder myBuffer;
+
+ private BufferUpdater(StringBuilder buffer) {
+ myBuffer = buffer;
+ }
+
+ @Override
+ protected void textChanged(DocumentEvent e) {
+ myBuffer.delete(0, myBuffer.length());
+ try {
+ myBuffer.append(e.getDocument().getText(0, e.getDocument().getLength()));
+ }
+ catch (BadLocationException e1) {
+ e1.printStackTrace();
+ }
+ }
+ }
+}
diff --git a/python/edu/learn-python/src/com/jetbrains/python/edu/ui/StudyToolWindowFactory.java b/python/edu/learn-python/src/com/jetbrains/python/edu/ui/StudyToolWindowFactory.java
new file mode 100644
index 000000000000..a553978c416a
--- /dev/null
+++ b/python/edu/learn-python/src/com/jetbrains/python/edu/ui/StudyToolWindowFactory.java
@@ -0,0 +1,81 @@
+package com.jetbrains.python.edu.ui;
+
+import com.intellij.openapi.project.DumbAware;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.wm.ToolWindow;
+import com.intellij.openapi.wm.ToolWindowFactory;
+import com.intellij.ui.JBColor;
+import com.intellij.ui.content.Content;
+import com.intellij.ui.content.ContentFactory;
+import com.intellij.util.ui.UIUtil;
+import com.jetbrains.python.edu.StudyTaskManager;
+import com.jetbrains.python.edu.course.Course;
+import com.jetbrains.python.edu.course.Lesson;
+import com.jetbrains.python.edu.course.LessonInfo;
+import com.jetbrains.python.edu.course.StudyStatus;
+import org.jetbrains.annotations.NotNull;
+
+import javax.swing.*;
+import java.awt.*;
+import java.util.List;
+
+public class StudyToolWindowFactory implements ToolWindowFactory, DumbAware {
+ public static final String STUDY_TOOL_WINDOW = "Course Description";
+ JPanel contentPanel = new JPanel();
+
+ @Override
+ public void createToolWindowContent(@NotNull final Project project, @NotNull final ToolWindow toolWindow) {
+ if (StudyTaskManager.getInstance(project).getCourse() != null) {
+ contentPanel.setLayout(new BoxLayout(contentPanel, BoxLayout.PAGE_AXIS));
+ contentPanel.add(Box.createRigidArea(new Dimension(10, 0)));
+ StudyTaskManager taskManager = StudyTaskManager.getInstance(project);
+ Course course = taskManager.getCourse();
+ if (course == null) {
+ return;
+ }
+ String courseName = UIUtil.toHtml("<h1>" + course.getName() + "</h1>", 10);
+ String description = UIUtil.toHtml(course.getDescription(), 5);
+ String author = taskManager.getCourse().getAuthor();
+ String authorLabel = UIUtil.toHtml("<b>Author: </b>" + author, 5);
+ contentPanel.add(new JLabel(courseName));
+ contentPanel.add(new JLabel(authorLabel));
+ contentPanel.add(Box.createRigidArea(new Dimension(0, 10)));
+ contentPanel.add(new JLabel(description));
+
+ int taskNum = 0;
+ int taskSolved = 0;
+ int lessonsCompleted = 0;
+ List<Lesson> lessons = course.getLessons();
+ for (Lesson lesson : lessons) {
+ if (lesson.getStatus() == StudyStatus.Solved) {
+ lessonsCompleted++;
+ }
+ LessonInfo lessonInfo = lesson.getLessonInfo();
+ taskNum += lessonInfo.getTaskNum();
+ taskSolved += lessonInfo.getTaskSolved();
+ }
+ String completedLessons = String.format("%d of %d lessons completed", lessonsCompleted, course.getLessons().size());
+ String completedTasks = String.format("%d of %d tasks completed", taskSolved, taskNum);
+ String tasksLeft = String.format("%d of %d tasks left", taskNum - taskSolved, taskNum);
+ contentPanel.add(Box.createVerticalStrut(10));
+ addStatistics(completedLessons);
+ addStatistics(completedTasks);
+
+ double percent = (taskSolved * 100.0) / taskNum;
+ contentPanel.add(Box.createRigidArea(new Dimension(0, 10)));
+ StudyProgressBar studyProgressBar = new StudyProgressBar(percent / 100, JBColor.GREEN, 40, 10);
+ contentPanel.add(studyProgressBar);
+ addStatistics(tasksLeft);
+ ContentFactory contentFactory = ContentFactory.SERVICE.getInstance();
+ Content content = contentFactory.createContent(contentPanel, "", true);
+ toolWindow.getContentManager().addContent(content);
+ }
+ }
+
+ private void addStatistics(String statistics) {
+ String labelText = UIUtil.toHtml(statistics, 5);
+ contentPanel.add(Box.createRigidArea(new Dimension(0, 10)));
+ JLabel statisticLabel = new JLabel(labelText);
+ contentPanel.add(statisticLabel);
+ }
+}