diff --git a/python/educational-core/student/resources/META-INF/plugin.xml b/python/educational-core/student/resources/META-INF/plugin.xml
index 1ccf94d72337..24cce69766c1 100644
--- a/python/educational-core/student/resources/META-INF/plugin.xml
+++ b/python/educational-core/student/resources/META-INF/plugin.xml
@@ -37,6 +37,9 @@
+ >
+
+
@@ -93,4 +96,7 @@
+
+
+
\ No newline at end of file
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 09cddf9b8e28..61d9e78570d6 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,6 @@ 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.settings.ModifiableSettingsPanel;
import com.jetbrains.edu.learning.ui.StudyToolWindow;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -41,9 +40,6 @@ public interface StudyPluginConfigurator {
StudyAfterCheckAction[] getAfterCheckActions();
@NotNull String getLanguageScriptUrl();
-
- @Nullable
- ModifiableSettingsPanel getSettingsPanel();
boolean accept(@NotNull final Project project);
}
diff --git a/python/educational-core/student/src/com/jetbrains/edu/learning/settings/ModifiableSettingsPanel.java b/python/educational-core/student/src/com/jetbrains/edu/learning/settings/ModifiableSettingsPanel.java
deleted file mode 100644
index 101fcb452397..000000000000
--- a/python/educational-core/student/src/com/jetbrains/edu/learning/settings/ModifiableSettingsPanel.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package com.jetbrains.edu.learning.settings;
-
-
-import org.jetbrains.annotations.NotNull;
-
-import javax.swing.*;
-
-public interface ModifiableSettingsPanel {
- void apply();
-
- void reset();
-
- void resetCredentialsModification();
-
- boolean isModified();
-
- @NotNull
- JComponent getPanel();
-}
diff --git a/python/educational-core/student/src/com/jetbrains/edu/learning/settings/StudyBaseSettingsPanel.form b/python/educational-core/student/src/com/jetbrains/edu/learning/settings/StudyBaseSettingsPanel.form
deleted file mode 100644
index 5ee9dc512466..000000000000
--- a/python/educational-core/student/src/com/jetbrains/edu/learning/settings/StudyBaseSettingsPanel.form
+++ /dev/null
@@ -1,91 +0,0 @@
-
-
diff --git a/python/educational-core/student/src/com/jetbrains/edu/learning/settings/StudyConfigurable.java b/python/educational-core/student/src/com/jetbrains/edu/learning/settings/StudyConfigurable.java
index eff51e506e35..45e40b5b5549 100644
--- a/python/educational-core/student/src/com/jetbrains/edu/learning/settings/StudyConfigurable.java
+++ b/python/educational-core/student/src/com/jetbrains/edu/learning/settings/StudyConfigurable.java
@@ -15,36 +15,22 @@
*/
package com.jetbrains.edu.learning.settings;
-import com.intellij.openapi.options.ConfigurationException;
-import com.intellij.openapi.options.SearchableConfigurable;
+import com.intellij.openapi.options.CompositeConfigurable;
+import com.intellij.openapi.options.ex.ConfigurableWrapper;
import com.intellij.openapi.ui.VerticalFlowLayout;
-import com.jetbrains.edu.learning.StudyPluginConfigurator;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
-import java.util.ArrayList;
+import java.util.List;
-public class StudyConfigurable implements SearchableConfigurable {
+public class StudyConfigurable extends CompositeConfigurable {
public static final String ID = "com.jetbrains.edu.learning.stepic.EduConfigurable";
private JPanel myMainPanel;
- private ArrayList myPluginsSettingsPanels;
- private StudyBaseSettingsPanel mySettingsPanel;
public StudyConfigurable() {
- }
-
- @NotNull
- @Override
- public String getId() {
- return ID;
- }
-
- @Nullable
- @Override
- public Runnable enableSearch(String option) {
- return null;
+ myMainPanel = new JPanel(new VerticalFlowLayout());
}
@Nls
@@ -62,63 +48,25 @@ public class StudyConfigurable implements SearchableConfigurable {
@Nullable
@Override
public JComponent createComponent() {
- if (myMainPanel == null) {
- myMainPanel = new JPanel(new VerticalFlowLayout());
- }
- mySettingsPanel = new StudyBaseSettingsPanel();
- myMainPanel.add(mySettingsPanel.getPanel());
-
- myPluginsSettingsPanels = new ArrayList<>();
- StudyPluginConfigurator[] extensions = StudyPluginConfigurator.EP_NAME.getExtensions();
- for (StudyPluginConfigurator configurator: extensions) {
- final ModifiableSettingsPanel settingsPanel = configurator.getSettingsPanel();
- if (settingsPanel != null) {
- myPluginsSettingsPanels.add(settingsPanel);
- myMainPanel.add(settingsPanel.getPanel());
+ myMainPanel.removeAll();
+ for (int i = 0; i < getConfigurables().size(); i++) {
+ StudyOptionsProvider provider = getConfigurables().get(i);
+ JComponent component = provider.createComponent();
+ if (component != null) {
+ myMainPanel.add(component);
}
}
return myMainPanel;
}
@Override
- public boolean isModified() {
- if (mySettingsPanel != null) {
- boolean isModified = mySettingsPanel.isModified();
- if (myPluginsSettingsPanels != null && !myPluginsSettingsPanels.isEmpty()) {
- for (ModifiableSettingsPanel settingsPanel: myPluginsSettingsPanels) {
- isModified &= settingsPanel.isModified();
- }
- }
- return isModified;
- }
- return false;
- }
-
- public void apply() throws ConfigurationException {
- if (myMainPanel != null) {
- mySettingsPanel.apply();
- if (myPluginsSettingsPanels != null && !myPluginsSettingsPanels.isEmpty()) {
- for (ModifiableSettingsPanel settingsPanel: myPluginsSettingsPanels) {
- settingsPanel.apply();
- }
- }
- }
- }
-
- public void reset() {
- if (myMainPanel != null) {
- mySettingsPanel.apply();
- if (myPluginsSettingsPanels != null && !myPluginsSettingsPanels.isEmpty()) {
- for (ModifiableSettingsPanel settingsPanel: myPluginsSettingsPanels) {
- settingsPanel.reset();
- }
- }
- }
+ public void disposeUIResources() {
+ super.disposeUIResources();
}
@Override
- public void disposeUIResources() {
- myMainPanel = null;
+ protected List createConfigurables() {
+ return ConfigurableWrapper.createConfigurables(StudyOptionsProviderEP.EP_NAME);
}
}
diff --git a/python/educational-core/student/src/com/jetbrains/edu/learning/settings/StudyOptionsProvider.java b/python/educational-core/student/src/com/jetbrains/edu/learning/settings/StudyOptionsProvider.java
new file mode 100644
index 000000000000..79324b2a3f57
--- /dev/null
+++ b/python/educational-core/student/src/com/jetbrains/edu/learning/settings/StudyOptionsProvider.java
@@ -0,0 +1,6 @@
+package com.jetbrains.edu.learning.settings;
+
+import com.intellij.openapi.options.UnnamedConfigurable;
+
+public interface StudyOptionsProvider extends UnnamedConfigurable {
+}
diff --git a/python/educational-core/student/src/com/jetbrains/edu/learning/settings/StudyOptionsProviderEP.java b/python/educational-core/student/src/com/jetbrains/edu/learning/settings/StudyOptionsProviderEP.java
new file mode 100644
index 000000000000..5c43b97a7bf6
--- /dev/null
+++ b/python/educational-core/student/src/com/jetbrains/edu/learning/settings/StudyOptionsProviderEP.java
@@ -0,0 +1,9 @@
+package com.jetbrains.edu.learning.settings;
+
+import com.intellij.openapi.extensions.ExtensionPointName;
+import com.intellij.openapi.options.ConfigurableEP;
+
+public class StudyOptionsProviderEP extends ConfigurableEP {
+ public static final ExtensionPointName
+ EP_NAME = ExtensionPointName.create("Edu.optionsProvider");
+}
diff --git a/python/educational-core/student/src/com/jetbrains/edu/learning/stepic/StepicOptionsProvider.java b/python/educational-core/student/src/com/jetbrains/edu/learning/stepic/StepicOptionsProvider.java
new file mode 100644
index 000000000000..921200ef4937
--- /dev/null
+++ b/python/educational-core/student/src/com/jetbrains/edu/learning/stepic/StepicOptionsProvider.java
@@ -0,0 +1,38 @@
+package com.jetbrains.edu.learning.stepic;
+
+import com.intellij.openapi.options.ConfigurationException;
+import com.jetbrains.edu.learning.settings.StudyOptionsProvider;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+
+public class StepicOptionsProvider implements StudyOptionsProvider{
+
+ private StepicStudyOptions myPanel;
+
+ @Nullable
+ @Override
+ public JComponent createComponent() {
+ myPanel = new StepicStudyOptions();
+ return myPanel.getPanel();
+ }
+
+ @Override
+ public boolean isModified() {
+ return myPanel.isModified();
+ }
+
+ @Override
+ public void apply() throws ConfigurationException {
+ myPanel.apply();
+ }
+
+ @Override
+ public void reset() {
+ myPanel.reset();
+ }
+
+ @Override
+ public void disposeUIResources() {
+ }
+}
diff --git a/python/educational-core/student/src/com/jetbrains/edu/learning/stepic/StepicStudyOptions.form b/python/educational-core/student/src/com/jetbrains/edu/learning/stepic/StepicStudyOptions.form
new file mode 100644
index 000000000000..86fa610cb50e
--- /dev/null
+++ b/python/educational-core/student/src/com/jetbrains/edu/learning/stepic/StepicStudyOptions.form
@@ -0,0 +1,69 @@
+
+
diff --git a/python/educational-core/student/src/com/jetbrains/edu/learning/settings/StudyBaseSettingsPanel.java b/python/educational-core/student/src/com/jetbrains/edu/learning/stepic/StepicStudyOptions.java
similarity index 89%
rename from python/educational-core/student/src/com/jetbrains/edu/learning/settings/StudyBaseSettingsPanel.java
rename to python/educational-core/student/src/com/jetbrains/edu/learning/stepic/StepicStudyOptions.java
index 2b3135c9e65b..c3994496fef7 100644
--- a/python/educational-core/student/src/com/jetbrains/edu/learning/settings/StudyBaseSettingsPanel.java
+++ b/python/educational-core/student/src/com/jetbrains/edu/learning/stepic/StepicStudyOptions.java
@@ -13,13 +13,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.jetbrains.edu.learning.settings;
+package com.jetbrains.edu.learning.stepic;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.ui.DocumentAdapter;
-import com.intellij.util.ui.UIUtil;
-import com.jetbrains.edu.learning.stepic.EduStepicConnector;
-import com.jetbrains.edu.learning.stepic.StudySettings;
+import com.jetbrains.edu.learning.settings.StudyOptionsProvider;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -31,7 +29,7 @@ import javax.swing.text.PlainDocument;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
-public class StudyBaseSettingsPanel implements ModifiableSettingsPanel{
+public class StepicStudyOptions implements StudyOptionsProvider {
private static final String DEFAULT_PASSWORD_TEXT = "************";
private JTextField myLoginTextField;
private JPasswordField myPasswordField;
@@ -39,7 +37,7 @@ public class StudyBaseSettingsPanel implements ModifiableSettingsPanel{
private boolean myCredentialsModified;
- public StudyBaseSettingsPanel() {
+ public StepicStudyOptions() {
myPasswordField.getDocument().addDocumentListener(new DocumentAdapter() {
@Override
protected void textChanged(DocumentEvent e) {
@@ -69,7 +67,6 @@ public class StudyBaseSettingsPanel implements ModifiableSettingsPanel{
public void focusLost(FocusEvent e) {
}
});
- myPane.setBorder(BorderFactory.createMatteBorder(1, 0, 0, 0, UIUtil.getBoundsColor()));
reset();
}
@@ -79,7 +76,6 @@ public class StudyBaseSettingsPanel implements ModifiableSettingsPanel{
}
@NotNull
- @Override
public JComponent getPanel() {
return myPane;
}
@@ -102,7 +98,7 @@ public class StudyBaseSettingsPanel implements ModifiableSettingsPanel{
myPasswordField.setText(StringUtil.isEmpty(password) ? null : password);
}
- @Override
+
public void reset() {
final StudySettings studySettings = StudySettings.getInstance();
setLogin(studySettings.getLogin());
@@ -112,6 +108,10 @@ public class StudyBaseSettingsPanel implements ModifiableSettingsPanel{
}
@Override
+ public void disposeUIResources() {
+
+ }
+
public void apply() {
if (myCredentialsModified) {
final StudySettings studySettings = StudySettings.getInstance();
@@ -124,12 +124,16 @@ public class StudyBaseSettingsPanel implements ModifiableSettingsPanel{
resetCredentialsModification();
}
+ @Nullable
@Override
+ public JComponent createComponent() {
+ return myPane;
+ }
+
public boolean isModified() {
return myCredentialsModified;
}
-
- @Override
+
public void resetCredentialsModification() {
myCredentialsModified = false;
}
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 88688a8ae8a5..5a163337ecfa 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,9 +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.settings.ModifiableSettingsPanel;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
public class PyStudyPluginConfigurator extends StudyBasePluginConfigurator {
@@ -38,10 +36,4 @@ public class PyStudyPluginConfigurator extends StudyBasePluginConfigurator {
Course course = taskManager.getCourse();
return course != null && "Python".equals(course.getLanguage()) && "PyCharm".equals(course.getCourseType());
}
-
- @Nullable
- @Override
- public ModifiableSettingsPanel getSettingsPanel() {
- return null;
- }
}