diff --git a/python/educational-core/educational-core.iml b/python/educational-core/educational-core.iml
index 8433b9de516e..1df588c98a73 100644
--- a/python/educational-core/educational-core.iml
+++ b/python/educational-core/educational-core.iml
@@ -8,5 +8,12 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/python/educational-core/student/lib/twitter4j-core-4.0.4.jar b/python/educational-core/student/lib/twitter4j-core-4.0.4.jar
new file mode 100644
index 000000000000..029abce2bc28
Binary files /dev/null and b/python/educational-core/student/lib/twitter4j-core-4.0.4.jar differ
diff --git a/python/educational-core/student/resources/META-INF/plugin.xml b/python/educational-core/student/resources/META-INF/plugin.xml
index 3e10b6a2bb2e..9d5142d93775 100644
--- a/python/educational-core/student/resources/META-INF/plugin.xml
+++ b/python/educational-core/student/resources/META-INF/plugin.xml
@@ -80,8 +80,6 @@
displayName="Educational"/>
-
diff --git a/python/educational-core/student/src/com/jetbrains/edu/learning/StudyBasePluginConfigurator.java b/python/educational-core/student/src/com/jetbrains/edu/learning/StudyBasePluginConfigurator.java
index e1900e133df5..801410c8d431 100644
--- a/python/educational-core/student/src/com/jetbrains/edu/learning/StudyBasePluginConfigurator.java
+++ b/python/educational-core/student/src/com/jetbrains/edu/learning/StudyBasePluginConfigurator.java
@@ -6,9 +6,11 @@ import com.intellij.openapi.fileEditor.FileEditorManagerEvent;
import com.intellij.openapi.fileEditor.FileEditorManagerListener;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
+import com.jetbrains.edu.learning.actions.*;
+import com.jetbrains.edu.learning.courseFormat.StudyStatus;
import com.jetbrains.edu.learning.courseFormat.Task;
import com.jetbrains.edu.learning.courseFormat.TaskFile;
-import com.jetbrains.edu.learning.actions.*;
+import com.jetbrains.edu.learning.twitter.StudyTwitterUtils;
import com.jetbrains.edu.learning.ui.StudyToolWindow;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -93,4 +95,44 @@ public abstract class StudyBasePluginConfigurator implements StudyPluginConfigur
public StudyAfterCheckAction[] getAfterCheckActions() {
return null;
}
+
+ @NotNull
+ @Override
+ public String getConsumerKey(@NotNull Project project) {
+ return "";
+ }
+
+ @NotNull
+ @Override
+ public String getConsumerSecret(@NotNull Project project) {
+ return "";
+ }
+
+ @Override
+ public void storeTwitterTokens(@NotNull Project project, @NotNull String accessToken, @NotNull String tokenSecret) {
+ // do nothing
+ }
+
+ @NotNull
+ @Override
+ public String getTwitterTokenSecret(@NotNull Project project) {
+ return "";
+ }
+
+ @NotNull
+ @Override
+ public String getTwitterAccessToken(@NotNull Project project) {
+ return "";
+ }
+
+ @Override
+ public boolean askToTweet(@NotNull Project project, Task solvedTask, StudyStatus statusBeforeCheck) {
+ return false;
+ }
+
+ @Nullable
+ @Override
+ public StudyTwitterUtils.TwitterDialogPanel getTweetDialogPanel(@NotNull Task solvedTask) {
+ return null;
+ }
}
diff --git a/python/educational-core/student/src/com/jetbrains/edu/learning/StudyPluginConfigurator.java b/python/educational-core/student/src/com/jetbrains/edu/learning/StudyPluginConfigurator.java
index 4561c2b903aa..4aa1f272acb5 100644
--- a/python/educational-core/student/src/com/jetbrains/edu/learning/StudyPluginConfigurator.java
+++ b/python/educational-core/student/src/com/jetbrains/edu/learning/StudyPluginConfigurator.java
@@ -5,7 +5,10 @@ import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.fileEditor.FileEditorManagerListener;
import com.intellij.openapi.project.Project;
import com.jetbrains.edu.learning.actions.StudyAfterCheckAction;
+import com.jetbrains.edu.learning.courseFormat.StudyStatus;
+import com.jetbrains.edu.learning.courseFormat.Task;
import com.jetbrains.edu.learning.settings.ModifiableSettingsPanel;
+import com.jetbrains.edu.learning.twitter.StudyTwitterUtils;
import com.jetbrains.edu.learning.ui.StudyToolWindow;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -18,7 +21,6 @@ public interface StudyPluginConfigurator {
/**
* Provide action group that should be placed on the tool window toolbar.
- * @param project
* @return
*/
@NotNull
@@ -26,7 +28,6 @@ public interface StudyPluginConfigurator {
/**
* Provide panels, that could be added to Task tool window.
- * @param project
* @return Map from panel id, i.e. "Task description", to panel itself.
*/
@NotNull
@@ -45,9 +46,50 @@ public interface StudyPluginConfigurator {
StudyAfterCheckAction[] getAfterCheckActions();
@NotNull String getLanguageScriptUrl();
-
- boolean accept(@NotNull final Project project);
@Nullable
ModifiableSettingsPanel getSettingsPanel();
+
+ /**
+ * To implement tweeting you should register you app in twitter. For registered application twitter provide
+ * consumer key and consumer secret, that are used for authorize by OAuth.
+ * @return consumer key for current educational plugin
+ */
+ @NotNull String getConsumerKey(@NotNull final Project project);
+
+ /**
+ * To implement tweeting you should register you app in twitter. For registered application twitter provide
+ * consumer key and consumer secret, that are used for authorize by OAuth.
+ * @return consumer secret for current educational plugin
+ */
+ @NotNull String getConsumerSecret(@NotNull final Project project);
+
+ /**
+ * The plugin implemented tweeting should define policy when user will be asked to tweet.
+ *@param statusBeforeCheck @return
+ */
+ boolean askToTweet(@NotNull final Project project, Task solvedTask, StudyStatus statusBeforeCheck);
+
+ /**
+ * Stores access token and token secret, obtained by authorizing PyCharm.
+ */
+ void storeTwitterTokens(@NotNull final Project project, @NotNull final String accessToken, @NotNull final String tokenSecret);
+
+ /**
+ * @return stored access token
+ */
+ @NotNull String getTwitterAccessToken(@NotNull Project project);
+
+ /**
+ * @return stored token secret
+ */
+ @NotNull String getTwitterTokenSecret(@NotNull Project project);
+
+ /**
+ * @return panel that will be shown to user in ask to tweet dialog.
+ */
+ @Nullable
+ StudyTwitterUtils.TwitterDialogPanel getTweetDialogPanel(@NotNull Task solvedTask);
+
+ boolean accept(@NotNull final Project project);
}
diff --git a/python/educational-core/student/src/com/jetbrains/edu/learning/actions/StudyAfterCheckAction.java b/python/educational-core/student/src/com/jetbrains/edu/learning/actions/StudyAfterCheckAction.java
index b85df4256cf8..ecd467777219 100644
--- a/python/educational-core/student/src/com/jetbrains/edu/learning/actions/StudyAfterCheckAction.java
+++ b/python/educational-core/student/src/com/jetbrains/edu/learning/actions/StudyAfterCheckAction.java
@@ -1,8 +1,8 @@
package com.jetbrains.edu.learning.actions;
import com.intellij.openapi.project.Project;
-import com.jetbrains.edu.courseFormat.StudyStatus;
-import com.jetbrains.edu.courseFormat.Task;
+import com.jetbrains.edu.learning.courseFormat.StudyStatus;
+import com.jetbrains.edu.learning.courseFormat.Task;
import org.jetbrains.annotations.NotNull;
public abstract class StudyAfterCheckAction {
diff --git a/python/educational-core/student/src/com/jetbrains/edu/learning/checker/StudyCheckTask.java b/python/educational-core/student/src/com/jetbrains/edu/learning/checker/StudyCheckTask.java
index bdeb215a89f1..9a372fe39fc1 100644
--- a/python/educational-core/student/src/com/jetbrains/edu/learning/checker/StudyCheckTask.java
+++ b/python/educational-core/student/src/com/jetbrains/edu/learning/checker/StudyCheckTask.java
@@ -11,15 +11,15 @@ import com.intellij.openapi.ui.MessageType;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
-import com.jetbrains.edu.learning.core.EduUtils;
-import com.jetbrains.edu.learning.courseFormat.StudyStatus;
-import com.jetbrains.edu.learning.courseFormat.Task;
import com.jetbrains.edu.learning.StudyPluginConfigurator;
import com.jetbrains.edu.learning.StudyState;
import com.jetbrains.edu.learning.StudyTaskManager;
import com.jetbrains.edu.learning.StudyUtils;
import com.jetbrains.edu.learning.actions.StudyAfterCheckAction;
-import com.jetbrains.edu.learning.EduStepicConnector;
+import com.jetbrains.edu.learning.core.EduUtils;
+import com.jetbrains.edu.learning.courseFormat.StudyStatus;
+import com.jetbrains.edu.learning.courseFormat.Task;
+import com.jetbrains.edu.learning.stepic.EduStepicConnector;
import com.jetbrains.edu.learning.stepic.StudySettings;
import org.jetbrains.annotations.NotNull;
diff --git a/python/educational-core/student/src/com/jetbrains/edu/learning/twitter/StudyTwitterAction.java b/python/educational-core/student/src/com/jetbrains/edu/learning/twitter/StudyTwitterAction.java
new file mode 100644
index 000000000000..dd74afa0d273
--- /dev/null
+++ b/python/educational-core/student/src/com/jetbrains/edu/learning/twitter/StudyTwitterAction.java
@@ -0,0 +1,49 @@
+package com.jetbrains.edu.learning.twitter;
+
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.project.Project;
+import com.jetbrains.edu.learning.StudyPluginConfigurator;
+import com.jetbrains.edu.learning.StudyUtils;
+import com.jetbrains.edu.learning.actions.StudyAfterCheckAction;
+import com.jetbrains.edu.learning.courseFormat.StudyStatus;
+import com.jetbrains.edu.learning.courseFormat.Task;
+import org.jetbrains.annotations.NotNull;
+import twitter4j.Twitter;
+import twitter4j.TwitterException;
+
+/**
+ * Action that provide tweeting functionality to plugin.
+ * Is performed for every solved task and configured by StudyPluginConfigurator instance.
+ *
+ * In order to provide tweeting functionality in your plugin you should override twitter
+ * methods in StudyPluginConfigurator instance of your plugin.
+ */
+public class StudyTwitterAction extends StudyAfterCheckAction {
+ Logger LOG = Logger.getInstance(StudyTwitterAction.class);
+ @Override
+ public void run(@NotNull Project project, @NotNull Task solvedTask, StudyStatus statusBeforeCheck) {
+ try {
+ StudyPluginConfigurator configurator = StudyUtils.getConfigurator(project);
+ if (configurator == null) {
+ LOG.warn("Plugin configurator not found");
+ return;
+ }
+
+ if (configurator.askToTweet(project, solvedTask, statusBeforeCheck)) {
+ boolean isAuthorized = !configurator.getTwitterAccessToken(project).isEmpty();
+ Twitter twitter = StudyTwitterUtils.getTwitter(configurator.getConsumerKey(project), configurator.getConsumerSecret(project));
+ StudyTwitterUtils.configureTwitter(twitter, project, isAuthorized);
+ StudyTwitterUtils.TwitterDialogPanel panel = configurator.getTweetDialogPanel(solvedTask);
+ if (panel != null) {
+ StudyTwitterUtils.showPostTweetDialogAndPostTweet(twitter, panel);
+ }
+ else {
+ LOG.warn("Plugin didn't provide twitter panel");
+ }
+ }
+ }
+ catch (TwitterException e) {
+ LOG.warn(e.getMessage());
+ }
+ }
+}
diff --git a/python/educational-core/student/src/com/jetbrains/edu/learning/twitter/StudyTwitterUtils.java b/python/educational-core/student/src/com/jetbrains/edu/learning/twitter/StudyTwitterUtils.java
new file mode 100644
index 000000000000..3fdab6b6a761
--- /dev/null
+++ b/python/educational-core/student/src/com/jetbrains/edu/learning/twitter/StudyTwitterUtils.java
@@ -0,0 +1,212 @@
+package com.jetbrains.edu.learning.twitter;
+
+import com.intellij.ide.BrowserUtil;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.DialogBuilder;
+import com.intellij.openapi.ui.Messages;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.ui.DocumentAdapter;
+import com.intellij.ui.components.JBScrollPane;
+import com.jetbrains.edu.learning.StudyPluginConfigurator;
+import com.jetbrains.edu.learning.StudyUtils;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import twitter4j.StatusUpdate;
+import twitter4j.Twitter;
+import twitter4j.TwitterException;
+import twitter4j.TwitterFactory;
+import twitter4j.auth.AccessToken;
+import twitter4j.auth.RequestToken;
+import twitter4j.conf.ConfigurationBuilder;
+
+import javax.swing.*;
+import javax.swing.event.DocumentEvent;
+import javax.swing.event.DocumentListener;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+
+public class StudyTwitterUtils {
+ private static final Logger LOG = Logger.getInstance(StudyTwitterUtils.class);
+
+ /**
+ * Configure twitter instance: authorize if needed or set access token and token secret provided by configurator.
+ * @param twitter
+ * @param project
+ * @param isAuthorized
+ * @throws TwitterException
+ */
+ public static void configureTwitter(@NotNull final Twitter twitter, @NotNull final Project project,
+ final boolean isAuthorized) throws TwitterException {
+ if (!isAuthorized) {
+ authorize(project, twitter);
+ }
+ else {
+ StudyPluginConfigurator configurator = StudyUtils.getConfigurator(project);
+ if (configurator != null) {
+ getTwitterForAuthorizedApp(twitter, configurator.getTwitterAccessToken(project), configurator.getTwitterTokenSecret(project));
+ }
+ }
+ }
+
+ /**
+ * Set consumer key and secret.
+ * @param consumerKey
+ * @param consumerSecret
+ * @return
+ */
+ @NotNull
+ public static Twitter getTwitter(@NotNull final String consumerKey, @NotNull final String consumerSecret) {
+ ConfigurationBuilder configurationBuilder = new ConfigurationBuilder();
+ configurationBuilder.setOAuthConsumerKey(consumerKey);
+ configurationBuilder.setOAuthConsumerSecret(consumerSecret);
+ return new TwitterFactory(configurationBuilder.build()).getInstance();
+ }
+
+ /**
+ * Set access token and token secret in Twitter instance
+ * @param twitter
+ * @param accessToken
+ * @param tokenSecret
+ */
+ private static void getTwitterForAuthorizedApp(Twitter twitter, @NotNull String accessToken,
+ @NotNull String tokenSecret) {
+ AccessToken token = new AccessToken(accessToken, tokenSecret);
+ twitter.setOAuthAccessToken(token);
+ }
+
+ /**
+ * Authorize user and save tokens by StudyPluginConfigurator#storeTwitterTokens
+ * @param project
+ * @param twitter
+ * @throws TwitterException
+ */
+ public static void authorize(@NotNull final Project project, @NotNull final Twitter twitter) throws TwitterException {
+ RequestToken requestToken = twitter.getOAuthRequestToken();
+ BrowserUtil.browse(requestToken.getAuthorizationURL());
+
+ ApplicationManager.getApplication().invokeLater(() -> {
+ String pin = Messages.showInputDialog("Twitter PIN:", "Twitter Authorization", null, "", null);
+ try {
+ AccessToken token;
+ if (pin != null && pin.length() > 0) {
+ token = twitter.getOAuthAccessToken(requestToken, pin);
+ }
+ else {
+ token = twitter.getOAuthAccessToken();
+ }
+ StudyPluginConfigurator configurator = StudyUtils.getConfigurator(project);
+ if (configurator != null) {
+ configurator.storeTwitterTokens(project, token.getToken(), token.getTokenSecret());
+ }
+ else {
+ LOG.warn("Plugin configurator not found");
+ }
+ }
+ catch (TwitterException e) {
+ if (401 == e.getStatusCode()) {
+ LOG.warn("Unable to get the access token.");
+ }
+ else {
+ LOG.warn(e.getMessage());
+ }
+ }
+ });
+ }
+
+ /**
+ * Show twitter dialog, asking user to tweet about his achievements. Post tweet with provided by panel
+ * media and text.
+ * As a result of succeeded tweet twitter website is opened in default browser.
+ * @param twitter
+ * @param twitterDialogPanel
+ */
+ public static void showPostTweetDialogAndPostTweet(@NotNull Twitter twitter, @NotNull final TwitterDialogPanel twitterDialogPanel) {
+ ApplicationManager.getApplication().invokeLater(() -> {
+ DialogBuilder builder = new DialogBuilder();
+ twitterDialogPanel.addTextFieldVerifier(createTextFieldLengthDocumentListener(builder, twitterDialogPanel));
+ builder.title("Twitter");
+ builder.addOkAction().setText("Tweet");
+ builder.addCancelAction();
+ builder.setCenterPanel(new JBScrollPane(twitterDialogPanel));
+ builder.resizable(true);
+ if (builder.showAndGet()) {
+ StatusUpdate update = new StatusUpdate(twitterDialogPanel.getMessage());
+ try {
+ InputStream inputStream = twitterDialogPanel.getMediaSource();
+ if (inputStream != null) {
+ File imageFile = FileUtil.createTempFile("twitter_media", "gif");
+
+ FileUtil.copy(inputStream, new FileOutputStream(imageFile));
+ update.media(imageFile);
+ }
+ twitter.updateStatus(update);
+ BrowserUtil.browse("https://twitter.com/");
+ }
+ catch (IOException | TwitterException e) {
+ LOG.warn(e.getMessage());
+ Messages.showErrorDialog("Status wasn't updated. Please, check internet connection and try again", "Twitter");
+ }
+ }
+ });
+ }
+
+ /**
+ * Listener updates label indicating remaining symbols number like in twitter.
+ * @param builder
+ * @param panel
+ * @return
+ */
+ public static DocumentListener createTextFieldLengthDocumentListener(@NotNull DialogBuilder builder, @NotNull final TwitterDialogPanel panel) {
+ return new DocumentAdapter() {
+ @Override
+ protected void textChanged(DocumentEvent e) {
+ int length = e.getDocument().getLength();
+ if (length > 140 || length == 0) {
+ builder.setOkActionEnabled(false);
+ panel.getRemainSymbolsLabel().setText("" + String.valueOf(140 - length) + "");
+ }
+ else {
+ builder.setOkActionEnabled(true);
+ panel.getRemainSymbolsLabel().setText(String.valueOf(140 - length));
+ }
+
+ }
+ };
+ }
+
+ /**
+ * Class provides structure for twitter dialog panel
+ */
+ public abstract static class TwitterDialogPanel extends JPanel {
+
+ /**
+ * Provides tweet text
+ * @return
+ */
+ @NotNull public abstract String getMessage();
+
+ /**
+ *
+ * @return Input stream of media should be posted or null if there's nothing to post
+ */
+ @Nullable public abstract InputStream getMediaSource();
+
+ /**
+ *
+ * @return label that will be used to show remained symbol number
+ */
+ @NotNull public abstract JLabel getRemainSymbolsLabel();
+
+ /**
+ * Api to add document listener to field containing tweet text
+ * @param documentListener
+ */
+ public abstract void addTextFieldVerifier(@NotNull final DocumentListener documentListener);
+
+ }
+}
diff --git a/python/educational-core/student/student.iml b/python/educational-core/student/student.iml
index c4f9d2bccdb9..0ebe6c7ad38b 100644
--- a/python/educational-core/student/student.iml
+++ b/python/educational-core/student/student.iml
@@ -11,6 +11,8 @@
+
+
\ No newline at end of file
diff --git a/python/educational-python/build/pycharm_edu_build.gant b/python/educational-python/build/pycharm_edu_build.gant
index 25ca87b39d95..d78efb76507b 100644
--- a/python/educational-python/build/pycharm_edu_build.gant
+++ b/python/educational-python/build/pycharm_edu_build.gant
@@ -224,7 +224,9 @@ public layoutEducational(String classesPath, Set usedJars) {
private layoutPlugins(layouts) {
dir("plugins") {
- layouts.layoutPlugin("student")
+ layouts.layoutPlugin("student") {
+ fileset(dir: "$pythonCommunityHome/educational-core/student/lib")
+ }
layouts.layoutPlugin("student-python") {
dir("courses") {
fileset(dir: "$pythonEduHome/student-python/resources/courses")
diff --git a/python/educational-python/educational-python.iml b/python/educational-python/educational-python.iml
index 5832d9d1b31a..20278fc43f44 100644
--- a/python/educational-python/educational-python.iml
+++ b/python/educational-python/educational-python.iml
@@ -24,5 +24,6 @@
+
\ No newline at end of file
diff --git a/python/educational-python/student-python/src/com/jetbrains/edu/learning/PyStudyPluginConfigurator.java b/python/educational-python/student-python/src/com/jetbrains/edu/learning/PyStudyPluginConfigurator.java
index e5e6dbec1daf..88688a8ae8a5 100644
--- a/python/educational-python/student-python/src/com/jetbrains/edu/learning/PyStudyPluginConfigurator.java
+++ b/python/educational-python/student-python/src/com/jetbrains/edu/learning/PyStudyPluginConfigurator.java
@@ -3,10 +3,7 @@ package com.jetbrains.edu.learning;
import com.intellij.openapi.actionSystem.DefaultActionGroup;
import com.intellij.openapi.project.Project;
import com.jetbrains.edu.learning.courseFormat.Course;
-import com.jetbrains.edu.learning.actions.PyTwitterAction;
-import com.jetbrains.edu.learning.actions.StudyAfterCheckAction;
import com.jetbrains.edu.learning.settings.ModifiableSettingsPanel;
-import com.jetbrains.edu.learning.settings.PySettingsPanel;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -34,12 +31,6 @@ public class PyStudyPluginConfigurator extends StudyBasePluginConfigurator {
return getClass().getResource("/python.js").toExternalForm();
}
- @Nullable
- @Override
- public StudyAfterCheckAction[] getAfterCheckActions() {
- return new StudyAfterCheckAction[]{new PyTwitterAction()};
- }
-
@Override
public boolean accept(@NotNull Project project) {
StudyTaskManager taskManager = StudyTaskManager.getInstance(project);
@@ -51,6 +42,6 @@ public class PyStudyPluginConfigurator extends StudyBasePluginConfigurator {
@Nullable
@Override
public ModifiableSettingsPanel getSettingsPanel() {
- return new PySettingsPanel();
+ return null;
}
}
diff --git a/python/educational-python/student-python/src/com/jetbrains/edu/learning/settings/PySettingsPanel.form b/python/educational-python/student-python/src/com/jetbrains/edu/learning/settings/PySettingsPanel.form
deleted file mode 100644
index a51a16c9216f..000000000000
--- a/python/educational-python/student-python/src/com/jetbrains/edu/learning/settings/PySettingsPanel.form
+++ /dev/null
@@ -1,52 +0,0 @@
-
-
diff --git a/python/educational-python/student-python/src/com/jetbrains/edu/learning/settings/PySettingsPanel.java b/python/educational-python/student-python/src/com/jetbrains/edu/learning/settings/PySettingsPanel.java
deleted file mode 100644
index 240b567135bb..000000000000
--- a/python/educational-python/student-python/src/com/jetbrains/edu/learning/settings/PySettingsPanel.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package com.jetbrains.edu.learning.settings;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.project.ProjectUtil;
-import com.intellij.ui.components.JBCheckBox;
-import com.intellij.util.ui.UIUtil;
-import org.jetbrains.annotations.NotNull;
-
-import javax.swing.*;
-
-
-public class PySettingsPanel implements ModifiableSettingsPanel{
- private JBCheckBox myAskToTweetCheckBox;
- private JPanel myPanel;
- private boolean myIsModified = false;
-
- public PySettingsPanel() {
- myAskToTweetCheckBox.addActionListener(e -> myIsModified = true);
- myAskToTweetCheckBox.setSelected(PyStudySettings.getInstance(ProjectUtil.guessCurrentProject(myPanel)).askToTweet());
- myPanel.setBorder(BorderFactory.createMatteBorder(1, 0, 0, 0, UIUtil.getBoundsColor()));
- }
-
- @Override
- public void apply() {
- Project project = ProjectUtil.guessCurrentProject(myPanel);
- PyStudySettings.getInstance(project).setAskToTweet(myAskToTweetCheckBox.isSelected());
- }
-
- @Override
- public void reset() {
- Project project = ProjectUtil.guessCurrentProject(myPanel);
- PyStudySettings.getInstance(project).setAskToTweet(true);
- }
-
- @Override
- public void resetCredentialsModification() {
- myIsModified = false;
- }
-
- @Override
- public boolean isModified() {
- return myIsModified;
- }
-
- @NotNull
- public JPanel getPanel() {
- return myPanel;
- }
-}
diff --git a/python/educational-python/student-python/src/com/jetbrains/edu/learning/settings/PyStudySettings.java b/python/educational-python/student-python/src/com/jetbrains/edu/learning/settings/PyStudySettings.java
deleted file mode 100644
index b2bc22b0d18b..000000000000
--- a/python/educational-python/student-python/src/com/jetbrains/edu/learning/settings/PyStudySettings.java
+++ /dev/null
@@ -1,43 +0,0 @@
-package com.jetbrains.edu.learning.settings;
-
-import com.intellij.openapi.components.PersistentStateComponent;
-import com.intellij.openapi.components.ServiceManager;
-import com.intellij.openapi.components.State;
-import com.intellij.openapi.components.Storage;
-import com.intellij.openapi.project.Project;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-@SuppressWarnings("MethodMayBeStatic")
-@State(name = "PyStudySettings", storages = @Storage("py_study_settings.xml"))
-public class PyStudySettings implements PersistentStateComponent {
-
- private State myState = new State();
-
-
- public static class State {
- public boolean askToTweet = true;
- }
-
- public static PyStudySettings getInstance(@NotNull final Project project) {
- return ServiceManager.getService(project, PyStudySettings.class);
- }
- @Nullable
- @Override
- public State getState() {
- return myState;
- }
-
- @Override
- public void loadState(State state) {
- myState = state;
- }
-
- public boolean askToTweet() {
- return myState.askToTweet;
- }
-
- public void setAskToTweet(final boolean askToTweet) {
- myState.askToTweet = askToTweet;
- }
-}
\ No newline at end of file