summaryrefslogtreecommitdiff
path: root/python/edu
diff options
context:
space:
mode:
Diffstat (limited to 'python/edu')
-rw-r--r--python/edu/build/DMG_background.pngbin0 -> 20543 bytes
-rw-r--r--python/edu/build/build.xml46
-rw-r--r--python/edu/build/paths.nsi6
-rw-r--r--python/edu/build/plugin-list.txt11
-rw-r--r--python/edu/build/pycharm_edu_build.gant393
-rw-r--r--python/edu/build/pycharm_edu_launcher.properties3
-rw-r--r--python/edu/build/python-edu-build.iml14
-rw-r--r--python/edu/build/resources/PC_instCom.icobin0 -> 17542 bytes
-rw-r--r--python/edu/build/resources/PC_uninstCom.icobin0 -> 17542 bytes
-rw-r--r--python/edu/build/resources/headerlogo.bmpbin0 -> 25818 bytes
-rw-r--r--python/edu/build/resources/logo.bmpbin0 -> 154544 bytes
-rw-r--r--python/edu/build/resources/pycharm_inst.icobin0 -> 26694 bytes
-rw-r--r--python/edu/build/resources/pycharm_uninst.icobin0 -> 26694 bytes
-rw-r--r--python/edu/build/strings.nsi13
-rw-r--r--python/edu/main_pycharm_edu.iml21
-rw-r--r--python/edu/python-educational.iml29
-rw-r--r--python/edu/resources/idea/PyCharmEduApplicationInfo.xml23
-rw-r--r--python/edu/src/META-INF/PyCharmEduPlugin.xml36
-rw-r--r--python/edu/src/com/jetbrains/python/edu/PyCharmEduInitialConfigurator.java247
19 files changed, 842 insertions, 0 deletions
diff --git a/python/edu/build/DMG_background.png b/python/edu/build/DMG_background.png
new file mode 100644
index 000000000000..3b5a4b2c1b26
--- /dev/null
+++ b/python/edu/build/DMG_background.png
Binary files differ
diff --git a/python/edu/build/build.xml b/python/edu/build/build.xml
new file mode 100644
index 000000000000..913237c81f27
--- /dev/null
+++ b/python/edu/build/build.xml
@@ -0,0 +1,46 @@
+<project name="PyCharm Educational Edition" default="all">
+ <property name="project.home" value="${basedir}/../../.."/>
+ <property name="python.home" value="${basedir}"/>
+ <property name="out.dir" value="${project.home}/out"/>
+ <property name="tmp.dir" value="${project.home}/out/tmp"/>
+
+ <target name="cleanup">
+ <delete dir="${out.dir}" failonerror="false"/>
+ </target>
+
+ <target name="init">
+ <mkdir dir="${out.dir}"/>
+ <mkdir dir="${tmp.dir}"/>
+ </target>
+
+ <macrodef name="call_gant">
+ <attribute name="script" />
+ <sequential>
+ <java failonerror="true" jar="${project.home}/lib/ant/lib/ant-launcher.jar" fork="true">
+ <jvmarg line="-Xmx612m -XX:MaxPermSize=152m -Didea.build.number=${idea.build.number} &quot;-DideaPath=${idea.path}&quot;"/>
+ <sysproperty key="java.awt.headless" value="true"/>
+ <arg line="&quot;-Dgant.script=@{script}&quot;"/>
+ <arg line="&quot;-Dteamcity.build.tempDir=${tmp.dir}&quot;"/>
+ <arg line="&quot;-Didea.build.number=${idea.build.number}&quot;"/>
+ <arg line="&quot;-Didea.test.group=ALL_EXCLUDE_DEFINED&quot;"/>
+ <arg value="-f"/>
+ <arg value="${project.home}/build/gant.xml"/>
+ </java>
+ </sequential>
+ </macrodef>
+
+ <target name="build" depends="init">
+ <call_gant script="${python.home}/pycharm_edu_build.gant"/>
+ </target>
+
+ <!--<target name="plugin" depends="init">-->
+ <!--<call_gant script="${python.home}/build/python_plugin_build.gant"/>-->
+ <!--</target>-->
+ <!--
+ <target name="test" depends="init">
+ <call_gant script="${project.home}/build/scripts/tests.gant"/>
+ </target>
+ -->
+
+ <target name="all" depends="cleanup,build"/>
+</project>
diff --git a/python/edu/build/paths.nsi b/python/edu/build/paths.nsi
new file mode 100644
index 000000000000..910f2b3555b7
--- /dev/null
+++ b/python/edu/build/paths.nsi
@@ -0,0 +1,6 @@
+; Installer images
+!define IMAGES_LOCATION ${COMMUNITY_DIR}\python\build\resources
+;!define LICENSE_FILE ${BASE_DIR}\python\license\PyCharm_Preview_License
+!define PRODUCT_PROPERTIES_FILE ${BASE_DIR}\out\pycharmEDU\layout\bin\idea.properties
+!define PRODUCT_VM_OPTIONS_NAME pycharm.exe.vmoptions
+!define PRODUCT_VM_OPTIONS_FILE ${BASE_DIR}\out\pycharmEDU\win\bin\${PRODUCT_VM_OPTIONS_NAME}
diff --git a/python/edu/build/plugin-list.txt b/python/edu/build/plugin-list.txt
new file mode 100644
index 000000000000..ceaa60895918
--- /dev/null
+++ b/python/edu/build/plugin-list.txt
@@ -0,0 +1,11 @@
+svn4idea
+git4idea
+remote-servers-git
+github
+terminal
+IntelliLang
+IntelliLang-xml
+IntelliLang-js
+IntelliLang-python
+rest
+python-rest
diff --git a/python/edu/build/pycharm_edu_build.gant b/python/edu/build/pycharm_edu_build.gant
new file mode 100644
index 000000000000..8c857c159874
--- /dev/null
+++ b/python/edu/build/pycharm_edu_build.gant
@@ -0,0 +1,393 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import org.jetbrains.jps.LayoutInfo
+
+import static org.jetbrains.jps.idea.IdeaProjectLoader.guessHome
+
+setProperty("home", guessHome(this as Script))
+
+includeTargets << new File("${guessHome(this as Script)}/build/scripts/utils.gant")
+// signMacZip locates in ultimate_utils.gant
+ includeTargets << new File("${guessHome(this)}/ultimate/build/scripts/ultimate_utils.gant")
+includeTargets << new File("${guessHome(this)}/build/scripts/libLicenses.gant")
+
+requireProperty("buildNumber", requireProperty("build.number", snapshot))
+
+setProperty("ch", "$home")
+setProperty("pythonCommunityHome", "$ch/python")
+setProperty("pythonEduHome", "$ch/python/edu")
+
+// load ApplicationInfo.xml properties
+ant.xmlproperty(file: "$pythonEduHome/resources/idea/PyCharmEduApplicationInfo.xml", collapseAttributes: "true")
+
+setProperty("system_selector", "PyCharm${p("component.version.major")}0")
+setProperty("dryRun", false)
+setProperty("jdk16", guessJdk())
+
+//modules to compile
+setProperty("pluginFilter", new File("$pythonEduHome/build/plugin-list.txt").readLines())
+
+private List<String> pycharmPlatformApiModules() {
+ return [platformApiModules, "dom-openapi"].flatten()
+}
+
+
+private List pycharmImplementationModules() { //modules to put into pycharm.jar
+ return [platformImplementationModules, "dom-impl", "python-community", "python-ide-community", "python-educational", "python-openapi", "python-psi-api",
+ "platform-main"].flatten()
+}
+
+private List modules() {
+ return [
+ "python-pydev", "colorSchemes", pycharmPlatformApiModules(), pycharmImplementationModules(), pluginFilter
+ ].flatten()
+}
+
+private List approvedJars() {
+ def normalizedHome = ch.replace('\\', '/')
+ def normalizedPythonHome = pythonCommunityHome.replace('\\', '/')
+ return ["$normalizedHome/lib/", "$normalizedPythonHome/lib/", "$normalizedHome/xml/relaxng/lib/"]
+}
+
+class Paths {
+ final sandbox
+ final distAll
+ final distWin
+ final distMac
+ final distUnix
+ final artifacts
+ final ideaSystem
+ final ideaConfig
+
+ def Paths(String home) {
+ sandbox = "$home/out/pycharmEDU"
+
+ distAll = "$sandbox/layout"
+ distWin = "$sandbox/win"
+ distMac = "$sandbox/mac"
+ distUnix = "$sandbox/unix"
+ artifacts = "$sandbox/artifacts"
+
+ ideaSystem = "$sandbox/system"
+ ideaConfig = "$sandbox/config"
+ }
+}
+
+setProperty("paths", new Paths(home))
+setProperty("buildName", "PE-$buildNumber")
+
+target('default': "Build artifacts") {
+
+ loadProject()
+
+ projectBuilder.stage("Cleaning up sandbox folder")
+
+ projectBuilder.targetFolder = "${paths.sandbox}/classes"
+ projectBuilder.dryRun = dryRun
+
+ if (!dryRun) {
+ forceDelete(paths.sandbox)
+ ant.mkdir(dir: paths.sandbox)
+ }
+
+ ant.tstamp() {
+ format(property: "todayYear", pattern: "yyyy")
+ }
+
+ ant.patternset(id: "resources.included") {
+ include(name: "**/*.properties")
+ include(name: "fileTemplates/**/*")
+ include(name: "inspectionDescriptions/**/*")
+ include(name: "intentionDescriptions/**/*")
+ include(name: "tips/**/*")
+ include(name: "search/**/*")
+ }
+
+ ant.patternset(id: "resources.excluded") {
+ exclude(name: "**/*.properties")
+ exclude(name: "fileTemplates/**/*")
+ exclude(name: "fileTemplates")
+ exclude(name: "inspectionDescriptions/**/*")
+ exclude(name: "inspectionDescriptions")
+ exclude(name: "intentionDescriptions/**/*")
+ exclude(name: "intentionDescriptions")
+ exclude(name: "tips/**/*")
+ exclude(name: "tips")
+ }
+
+ zipSources(home, paths.artifacts)
+
+ def usedJars = buildModulesAndCollectUsedJars(modules(), approvedJars(), ["/ant/"])
+
+ layoutEducational("${paths.sandbox}/classes/production", usedJars)
+
+
+ //buildNSIS([paths.distAll, paths.distWin],
+ // "${pythonEduHome}/build/strings.nsi", "${pythonEduHome}/build/paths.nsi",
+ // "pycharm", false, true, ".py", system_selector)
+
+ def extraArgs = ["build.code": "pycharmEDU-${buildNumber}", "build.number": "PE-$buildNumber", "artifacts.path": "${paths.artifacts}"]
+ signMacZip("pycharm", extraArgs)
+ buildDmg("pycharm", "${pythonEduHome}/build/DMG_background.png", extraArgs)
+
+}
+
+public layoutEducational(String classesPath, Set usedJars) {
+ setProperty("pluginFilter", new File("$pythonEduHome/build/plugin-list.txt").readLines())
+
+ if (usedJars == null) {
+ usedJars = collectUsedJars(modules(), approvedJars(), ["/ant/"], null)
+ }
+
+ def appInfo = appInfoFile(classesPath)
+ def paths = new Paths(home)
+ buildSearchableOptions("${projectBuilder.moduleOutput(findModule("platform-resources"))}/search", [], {
+ projectBuilder.moduleRuntimeClasspath(findModule("main_pycharm_edu"), false).each {
+ ant.pathelement(location: it)
+ }
+ }, "-Didea.platform.prefix=PyCharmEdu -Didea.no.jre.check=true")
+
+ if (!dryRun) {
+ wireBuildDate("PE-${buildNumber}", appInfo)
+ }
+
+ Map args = [
+ buildNumber: "PE-${buildNumber}",
+ system_selector: system_selector,
+ ide_jvm_args: "-Didea.platform.prefix=PyCharmEdu -Didea.no.jre.check=true"]
+
+ LayoutInfo layoutInfo = layoutFull(args, paths.distAll, usedJars)
+ generateLicensesTable("$paths.artifacts/third-party-libraries.txt", layoutInfo.usedModules);
+
+ layoutWin(args, paths.distWin)
+ layoutUnix(args, paths.distUnix)
+ layoutMac(args, paths.distMac)
+
+ ant.echo(message: "PE-${buildNumber}", file: "${paths.distAll}/build.txt")
+
+ def launcher = "${paths.distWin}/bin/pycharm.exe"
+ List resourcePaths = ["$ch/community-resources/src",
+ "$ch/platform/icons/src",
+ "$pythonEduHome/resources"]
+ buildWinLauncher("$ch", "$ch/bin/WinLauncher/WinLauncher.exe", launcher,
+ appInfo, "$pythonEduHome/build/pycharm_edu_launcher.properties", system_selector, resourcePaths)
+
+ buildWinZip("${paths.artifacts}/pycharmPE-${buildNumber}.zip", [paths.distAll, paths.distWin])
+
+ String tarRoot = isEap() ? "pycharm-edu-$buildNumber" : "pycharm-edu-${p("component.version.major")}.${p("component.version.minor")}"
+ buildTarGz(tarRoot, "$paths.artifacts/pycharmPE-${buildNumber}.tar", [paths.distAll, paths.distUnix])
+
+ String macAppRoot = isEap() ? "PyCharm EDU ${p("component.version.major")}.${p("component.version.minor")} EAP.app/Contents" : "PyCharm EDU.app/Contents"
+ buildMacZip(macAppRoot, "${paths.artifacts}/pycharmEDU-${buildNumber}.sit", [paths.distAll], paths.distMac)
+}
+
+private layoutPlugins(layouts) {
+ dir("plugins") {
+ layouts.layoutPlugin("rest")
+ layouts.layoutPlugin("python-rest")
+ }
+
+ layouts.layoutCommunityPlugins(ch)
+}
+
+private String appInfoFile(String classesPath) {
+ return "$classesPath/python-educational/idea/PyCharmEduApplicationInfo.xml"
+}
+
+private layoutFull(Map args, String target, Set usedJars) {
+ def openapiModules = pycharmPlatformApiModules()
+ def superLayouts = includeFile("$ch/build/scripts/layouts.gant")
+
+ reassignAltClickToMultipleCarets("$ch")
+
+ def result = layout(target) {
+ dir("lib") {
+ jar("util.jar") {
+ module("util")
+ module("util-rt")
+ }
+
+ jar("openapi.jar") {
+ openapiModules.each { module it }
+ }
+
+ jar("annotations.jar") { module("annotations") }
+ jar("extensions.jar") { module("extensions") }
+
+ jar("pycharm.jar") {
+ pycharmImplementationModules().each {
+ module(it) {
+ exclude(name: "**/tips/**")
+ }
+ }
+ }
+
+ jar("pycharm-pydev.jar") {
+ module("python-pydev")
+ }
+
+ jar("bootstrap.jar") { module("bootstrap") }
+ jar("resources.jar") {
+ module("platform-resources")
+ module("colorSchemes")
+ }
+
+ jar("forms_rt.jar") {
+ module("forms_rt")
+ }
+
+ //noinspection GroovyAssignabilityCheck
+ jar([name: "resources_en.jar", duplicate: "preserve"]) {
+ // custom resources should go first
+ fileset(dir: "$pythonCommunityHome/resources") {
+ include(name: "**/tips/**")
+ }
+ module("platform-resources-en") {
+ ant.patternset {
+ exclude(name: "tips/images/switcher.png")
+ exclude(name: "tips/images/navigateToFilePath.gif")
+ }
+ }
+ }
+
+ jar("icons.jar") { module("icons") }
+ jar("boot.jar") { module("boot") }
+
+ usedJars.each {
+ fileset(file: it)
+ }
+
+ dir("libpty") {
+ fileset(dir: "$ch/lib/libpty") {
+ exclude(name: "*.txt")
+ }
+ }
+
+ dir("ext") {
+ fileset(dir: "$ch/lib") {
+ include(name: "cglib*.jar")
+ }
+ }
+
+ dir("src") {
+ fileset(dir: "$ch/lib/src") {
+ include(name: "trove4j_changes.txt")
+ include(name: "trove4j_src.jar")
+ }
+
+ jar("pycharm-pydev-src.zip") {
+ fileset(dir: "$pythonCommunityHome/pydevSrc")
+ }
+ jar("pycharm-openapi-src.zip") {
+ fileset(dir: "$pythonCommunityHome/openapi/src")
+ fileset(dir: "$pythonCommunityHome/psi-api/src")
+ }
+ }
+ }
+
+ dir("help") {
+ fileset(dir: "$home/python/help") {
+ include(name: "*.pdf")
+ }
+ }
+
+ dir("helpers") {
+ fileset(dir: "$pythonCommunityHome/helpers")
+ }
+
+ dir("license") {
+ fileset(dir: "$ch/license")
+ fileset(dir: "$ch") {
+ include(name: "LICENSE.txt")
+ include(name: "NOTICE.txt")
+ }
+ }
+
+ layoutPlugins(superLayouts)
+
+ dir("bin") {
+ fileset(dir: "$ch/bin") {
+ exclude(name: "appletviewer.policy")
+ include(name: "*.*")
+ }
+ }
+ }
+ patchPropertiesFile(target, args + [appendices: ["$home/build/conf/ideaJNC.properties"]])
+ return result
+}
+
+private layoutWin(Map args, String target) {
+ layout(target) {
+ dir("bin") {
+ fileset(dir: "$ch/bin/win") {
+ exclude(name: "breakgen*")
+ }
+ }
+
+ dir("skeletons") {
+ fileset(dir: "$pythonCommunityHome/skeletons") {
+ include(name: "skeletons-win*.zip")
+ }
+ }
+ }
+
+ winScripts(target, ch, "pycharm.bat", args)
+ winVMOptions(target, null, "pycharm.exe")
+
+ ant.copy(file: "$home/python/help/pycharmhelp.jar", todir: "$target/help", failonerror: false)
+}
+
+private layoutUnix(Map args, String target) {
+ layout(target) {
+ dir("bin") {
+ fileset(dir: "$ch/bin/linux") {
+ exclude(name: "libbreakgen*")
+ }
+ }
+ }
+
+ ant.copy(file: "$pythonCommunityHome/resources/PyCharmCore128.png", tofile: "$target/bin/pycharm.png")
+
+ unixScripts(target, ch, "pycharm.sh", args)
+ unixVMOptions(target, "pycharm")
+
+ ant.copy(file: "$home/python/help/pycharmhelp.jar", todir: "$target/help", failonerror: false)
+}
+
+private layoutMac(Map _args, String target) {
+ layout(target) {
+ dir("bin") {
+ fileset(dir: "$home/bin") {
+ include(name: "*.jnilib")
+ }
+ }
+
+ dir("skeletons") {
+ fileset(dir: "$pythonCommunityHome/skeletons") {
+ include(name: "skeletons-mac*.zip")
+ }
+ }
+ }
+
+ Map args = new HashMap(_args)
+ args.icns = "$pythonCommunityHome/resources/PyCharmCore.icns"
+ args.bundleIdentifier = "com.jetbrains.pycharm"
+ args.platform_prefix = "PyCharmEdu"
+ args.help_id = "PY"
+ args."idea.properties.path" = "${paths.distAll}/bin/idea.properties"
+ args."idea.properties" = ["idea.no.jre.check": true, "ide.mac.useNativeClipboard": "false"];
+ layoutMacApp(target, ch, args)
+}
diff --git a/python/edu/build/pycharm_edu_launcher.properties b/python/edu/build/pycharm_edu_launcher.properties
new file mode 100644
index 000000000000..d3554685ce3b
--- /dev/null
+++ b/python/edu/build/pycharm_edu_launcher.properties
@@ -0,0 +1,3 @@
+IDS_JDK_ENV_VAR=PYCHARM_JDK
+IDS_JDK_ONLY=false
+IDS_VM_OPTIONS=-Didea.platform.prefix=PyCharmEdu -Didea.no.jre.check=true -Didea.paths.selector=__PRODUCT_PATHS_SELECTOR__
diff --git a/python/edu/build/python-edu-build.iml b/python/edu/build/python-edu-build.iml
new file mode 100644
index 000000000000..bda177851580
--- /dev/null
+++ b/python/edu/build/python-edu-build.iml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="JAVA_MODULE" version="4">
+ <component name="NewModuleRootManager" inherit-compiler-output="true">
+ <exclude-output />
+ <content url="file://$MODULE_DIR$">
+ <sourceFolder url="file://$MODULE_DIR$" isTestSource="false" />
+ </content>
+ <orderEntry type="inheritedJdk" />
+ <orderEntry type="sourceFolder" forTests="false" />
+ <orderEntry type="library" name="Groovy" level="project" />
+ <orderEntry type="module" module-name="jps-standalone-builder" />
+ </component>
+</module>
+
diff --git a/python/edu/build/resources/PC_instCom.ico b/python/edu/build/resources/PC_instCom.ico
new file mode 100644
index 000000000000..44ecec9c8755
--- /dev/null
+++ b/python/edu/build/resources/PC_instCom.ico
Binary files differ
diff --git a/python/edu/build/resources/PC_uninstCom.ico b/python/edu/build/resources/PC_uninstCom.ico
new file mode 100644
index 000000000000..13e9f96f9987
--- /dev/null
+++ b/python/edu/build/resources/PC_uninstCom.ico
Binary files differ
diff --git a/python/edu/build/resources/headerlogo.bmp b/python/edu/build/resources/headerlogo.bmp
new file mode 100644
index 000000000000..c06099264961
--- /dev/null
+++ b/python/edu/build/resources/headerlogo.bmp
Binary files differ
diff --git a/python/edu/build/resources/logo.bmp b/python/edu/build/resources/logo.bmp
new file mode 100644
index 000000000000..0f0f82da7b1e
--- /dev/null
+++ b/python/edu/build/resources/logo.bmp
Binary files differ
diff --git a/python/edu/build/resources/pycharm_inst.ico b/python/edu/build/resources/pycharm_inst.ico
new file mode 100644
index 000000000000..6c75bcdbc441
--- /dev/null
+++ b/python/edu/build/resources/pycharm_inst.ico
Binary files differ
diff --git a/python/edu/build/resources/pycharm_uninst.ico b/python/edu/build/resources/pycharm_uninst.ico
new file mode 100644
index 000000000000..a5b9ad86ae94
--- /dev/null
+++ b/python/edu/build/resources/pycharm_uninst.ico
Binary files differ
diff --git a/python/edu/build/strings.nsi b/python/edu/build/strings.nsi
new file mode 100644
index 000000000000..fa10d421024c
--- /dev/null
+++ b/python/edu/build/strings.nsi
@@ -0,0 +1,13 @@
+!define MANUFACTURER "JetBrains"
+!define MUI_PRODUCT "PyCharm Educational Edition"
+!define PRODUCT_FULL_NAME "JetBrains PyCharm Educational Edition"
+!define PRODUCT_EXE_FILE "pycharm.exe"
+!define PRODUCT_ICON_FILE "PC_instCom.ico"
+!define PRODUCT_UNINST_ICON_FILE "PC_uninstCom.ico"
+!define PRODUCT_LOGO_FILE "logo.bmp"
+!define PRODUCT_HEADER_FILE "headerlogo.bmp"
+
+; if SHOULD_SET_DEFAULT_INSTDIR != 0 then default installation directory will be directory where highest-numbered PyCharm build has been installed
+; set to 1 for release build
+!define SHOULD_SET_DEFAULT_INSTDIR "0"
+
diff --git a/python/edu/main_pycharm_edu.iml b/python/edu/main_pycharm_edu.iml
new file mode 100644
index 000000000000..2acdd8733873
--- /dev/null
+++ b/python/edu/main_pycharm_edu.iml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="JAVA_MODULE" version="4">
+ <component name="NewModuleRootManager" inherit-compiler-output="true">
+ <exclude-output />
+ <orderEntry type="inheritedJdk" />
+ <orderEntry type="sourceFolder" forTests="false" />
+ <orderEntry type="module" module-name="bootstrap" />
+ <orderEntry type="module" module-name="colorSchemes" />
+ <orderEntry type="module" module-name="svn4idea" />
+ <orderEntry type="module" module-name="git4idea" />
+ <orderEntry type="module" module-name="relaxng" />
+ <orderEntry type="module" module-name="rest" />
+ <orderEntry type="module" module-name="python-helpers" />
+ <orderEntry type="module" module-name="terminal" />
+ <orderEntry type="module" module-name="python-ide-community" />
+ <orderEntry type="module" module-name="platform-main" />
+ <orderEntry type="module" module-name="ShortcutPromoter" />
+ <orderEntry type="module" module-name="python-educational" />
+ </component>
+</module>
+
diff --git a/python/edu/python-educational.iml b/python/edu/python-educational.iml
new file mode 100644
index 000000000000..92439c421c2d
--- /dev/null
+++ b/python/edu/python-educational.iml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="JAVA_MODULE" version="4">
+ <component name="NewModuleRootManager" inherit-compiler-output="true">
+ <exclude-output />
+ <content url="file://$MODULE_DIR$">
+ <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
+ <sourceFolder url="file://$MODULE_DIR$/resources" type="java-resource" />
+ <sourceFolder url="file://$MODULE_DIR$/gen" isTestSource="false" generated="true" />
+ </content>
+ <orderEntry type="inheritedJdk" />
+ <orderEntry type="sourceFolder" forTests="false" />
+ <orderEntry type="module" module-name="python-openapi" exported="" />
+ <orderEntry type="module" module-name="platform-impl" />
+ <orderEntry type="module" module-name="lang-impl" />
+ <orderEntry type="library" name="Guava" level="project" />
+ <orderEntry type="module" module-name="python-pydev" />
+ <orderEntry type="library" exported="" name="XmlRPC" level="project" />
+ <orderEntry type="module" module-name="xdebugger-api" />
+ <orderEntry type="library" name="http-client-3.1" level="project" />
+ <orderEntry type="module" module-name="RegExpSupport" exported="" />
+ <orderEntry type="module" module-name="testRunner" />
+ <orderEntry type="module" module-name="smRunner" />
+ <orderEntry type="module" module-name="spellchecker" />
+ <orderEntry type="module" module-name="xdebugger-impl" />
+ <orderEntry type="module" module-name="xml-psi-impl" />
+ <orderEntry type="module" module-name="python-community" />
+ </component>
+</module>
+
diff --git a/python/edu/resources/idea/PyCharmEduApplicationInfo.xml b/python/edu/resources/idea/PyCharmEduApplicationInfo.xml
new file mode 100644
index 000000000000..46695ef29ed4
--- /dev/null
+++ b/python/edu/resources/idea/PyCharmEduApplicationInfo.xml
@@ -0,0 +1,23 @@
+<component>
+ <company name="JetBrains s.r.o." url="http://www.jetbrains.com/?fromIDE"/>
+ <version major="3" minor="0" eap="true"/>
+ <build number="__BUILD_NUMBER__" date="__BUILD_DATE__"/>
+ <logo url="/pycharm_core_logo.png" textcolor="ffffff" progressColor="ffaa16" progressY="230" progressTailIcon="/community_progress_tail.png"/>
+ <about url="/pycharm_core_about.png" logoX="300" logoY="265" logoW="75" logoH="30" foreground="ffffff" linkColor="fca11a"/>
+ <icon size32="/PyCharmCore32.png" size16="/PyCharmCore16.png" size32opaque="/PyCharmCore32.png" size12="/PyCharmCore13.png" ico="PyCharmCore.ico"/>
+ <package code="__PACKAGE_CODE__"/>
+ <names product="PyCharm" fullname="PyCharm Educational Edition" script="charm"/>
+ <install-over minbuild="0" maxbuild="0" version="1.x"/>
+
+ <welcome-screen logo-url="/PyCharmCoreWelcomeScreen.png" caption-url="PyCharmCoreWelcomeCaption.png" slogan-url="/developSlogan.png"/>
+
+ <third-party url="http://confluence.jetbrains.com/display/PYH/Third-Party+Software+Used+by+PyCharm"/>
+
+ <update-urls logo-url="/Logo_welcomeScreen.png"
+ check="http://www.jetbrains.com/updates/updates.xml"
+ patches="http://download.jetbrains.com/python/"/>
+
+ <feedback eap-url="http://www.jetbrains.com/feedback/feedback.jsp?product=PyCharm&amp;build=$BUILD&amp;timezone=$TIMEZONE&amp;eval=$EVAL"
+ release-url="http://www.jetbrains.com/feedback/feedback.jsp?product=PyCharm&amp;build=$BUILD&amp;timezone=$TIMEZONE&amp;eval=$EVAL"/>
+ <help file="pycharmhelp.jar" root="pycharm"/>
+</component>
diff --git a/python/edu/src/META-INF/PyCharmEduPlugin.xml b/python/edu/src/META-INF/PyCharmEduPlugin.xml
new file mode 100644
index 000000000000..9adf03dfd9c8
--- /dev/null
+++ b/python/edu/src/META-INF/PyCharmEduPlugin.xml
@@ -0,0 +1,36 @@
+<idea-plugin version="2" xmlns:xi="http://www.w3.org/2001/XInclude">
+ <!-- Components and extensions declared in this file work ONLY in Pycharm Educational Edition -->
+
+ <application-components>
+ <component>
+ <implementation-class>com.jetbrains.python.edu.PyCharmEduInitialConfigurator$First</implementation-class>
+ <headless-implementation-class/>
+ </component>
+ </application-components>
+
+ <xi:include href="/META-INF/pycharm-core.xml" xpointer="xpointer(/idea-plugin/*)"/>
+
+ <xi:include href="/META-INF/python-core.xml" xpointer="xpointer(/idea-plugin/*)"/>
+
+
+ <actions>
+ <group overrides="true" class="com.intellij.openapi.actionSystem.EmptyActionGroup" id="ToolsMenu"/>
+
+ <group overrides="true" class="com.intellij.openapi.actionSystem.EmptyActionGroup" id="PrintExportGroup"/>
+ <group overrides="true" id="FileMainSettingsGroup">
+ <reference id="ShowSettings"/>
+ <separator/>
+ <reference id="ExportImportGroup"/>
+ </group>
+
+ <group overrides="true" class="com.intellij.openapi.actionSystem.EmptyActionGroup" id="EditBookmarksGroup"/>
+ <group overrides="true" class="com.intellij.openapi.actionSystem.EmptyActionGroup" id="AddToFavorites"/>
+ <group overrides="true" class="com.intellij.openapi.actionSystem.EmptyActionGroup" id="AddAllToFavorites"/>
+ <action overrides="true" class="com.intellij.openapi.actionSystem.EmptyAction" id="AddToFavoritesPopup"/>
+ <action overrides="true" class="com.intellij.openapi.actionSystem.EmptyAction" id="RemoveFromFavorites"/>
+
+ <action overrides="true" class="com.intellij.openapi.actionSystem.EmptyAction" id="NewHtmlFile"/>
+
+
+ </actions>
+</idea-plugin>
diff --git a/python/edu/src/com/jetbrains/python/edu/PyCharmEduInitialConfigurator.java b/python/edu/src/com/jetbrains/python/edu/PyCharmEduInitialConfigurator.java
new file mode 100644
index 000000000000..451c5193645e
--- /dev/null
+++ b/python/edu/src/com/jetbrains/python/edu/PyCharmEduInitialConfigurator.java
@@ -0,0 +1,247 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jetbrains.python.edu;
+
+import com.intellij.application.options.InitialConfigurationDialog;
+import com.intellij.codeInsight.CodeInsightSettings;
+import com.intellij.codeInsight.intention.IntentionActionBean;
+import com.intellij.codeInsight.intention.IntentionManager;
+import com.intellij.ide.AppLifecycleListener;
+import com.intellij.ide.GeneralSettings;
+import com.intellij.ide.RecentProjectsManagerBase;
+import com.intellij.ide.SelectInTarget;
+import com.intellij.ide.ui.UISettings;
+import com.intellij.ide.util.PropertiesComponent;
+import com.intellij.ide.util.TipDialog;
+import com.intellij.notification.EventLog;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.application.ModalityState;
+import com.intellij.openapi.editor.ex.EditorSettingsExternalizable;
+import com.intellij.openapi.extensions.Extensions;
+import com.intellij.openapi.extensions.ExtensionsArea;
+import com.intellij.openapi.fileChooser.impl.FileChooserUtil;
+import com.intellij.openapi.fileTypes.FileTypeManager;
+import com.intellij.openapi.keymap.Keymap;
+import com.intellij.openapi.keymap.ex.KeymapManagerEx;
+import com.intellij.openapi.keymap.impl.KeymapImpl;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.project.ProjectManager;
+import com.intellij.openapi.project.ProjectManagerAdapter;
+import com.intellij.openapi.project.ex.ProjectManagerEx;
+import com.intellij.openapi.util.Disposer;
+import com.intellij.openapi.util.Ref;
+import com.intellij.openapi.vfs.VfsUtil;
+import com.intellij.openapi.wm.ToolWindowEP;
+import com.intellij.openapi.wm.ToolWindowId;
+import com.intellij.openapi.wm.WindowManager;
+import com.intellij.platform.DirectoryProjectConfigurator;
+import com.intellij.platform.PlatformProjectViewOpener;
+import com.intellij.psi.codeStyle.CodeStyleSettings;
+import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
+import com.intellij.util.Alarm;
+import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.messages.MessageBus;
+import com.jetbrains.python.PythonLanguage;
+import com.jetbrains.python.codeInsight.PyCodeInsightSettings;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+
+import javax.swing.*;
+import java.util.Set;
+
+/**
+ * @author traff
+ */
+@SuppressWarnings({"UtilityClassWithoutPrivateConstructor", "UtilityClassWithPublicConstructor"})
+public class PyCharmEduInitialConfigurator {
+ @NonNls private static final String DISPLAYED_PROPERTY = "PyCharm.initialConfigurationShown";
+
+ @NonNls private static final String CONFIGURED = "PyCharm.InitialConfiguration";
+
+
+ public static class First {
+
+ public First() {
+ patchRootAreaExtensions();
+ }
+ }
+
+ /**
+ * @noinspection UnusedParameters
+ */
+ public PyCharmEduInitialConfigurator(MessageBus bus,
+ UISettings uiSettings,
+ CodeInsightSettings codeInsightSettings,
+ final PropertiesComponent propertiesComponent,
+ FileTypeManager fileTypeManager,
+ final ProjectManagerEx projectManager,
+ RecentProjectsManagerBase recentProjectsManager) {
+ if (!propertiesComponent.getBoolean(CONFIGURED, false)) {
+ propertiesComponent.setValue(CONFIGURED, "true");
+ recentProjectsManager.loadState(new RecentProjectsManagerBase.State());
+ propertiesComponent.setValue("toolwindow.stripes.buttons.info.shown", "true");
+ UISettings.getInstance().HIDE_TOOL_STRIPES = false;
+ uiSettings.SHOW_MEMORY_INDICATOR = false;
+ uiSettings.SHOW_DIRECTORY_FOR_NON_UNIQUE_FILENAMES = true;
+ codeInsightSettings.REFORMAT_ON_PASTE = CodeInsightSettings.NO_REFORMAT;
+
+ EditorSettingsExternalizable.getInstance().setVirtualSpace(false);
+ final CodeStyleSettings settings = CodeStyleSettingsManager.getInstance().getCurrentSettings();
+ settings.ALIGN_MULTILINE_PARAMETERS_IN_CALLS = true;
+ settings.getCommonSettings(PythonLanguage.getInstance()).ALIGN_MULTILINE_PARAMETERS_IN_CALLS = true;
+ UISettings.getInstance().SHOW_DIRECTORY_FOR_NON_UNIQUE_FILENAMES = true;
+ UISettings.getInstance().SHOW_MEMORY_INDICATOR = false;
+ final String ignoredFilesList = fileTypeManager.getIgnoredFilesList();
+ ApplicationManager.getApplication().invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ ApplicationManager.getApplication().runWriteAction(new Runnable() {
+ @Override
+ public void run() {
+ FileTypeManager.getInstance().setIgnoredFilesList(ignoredFilesList + ";*$py.class");
+ }
+ });
+ }
+ });
+ PyCodeInsightSettings.getInstance().SHOW_IMPORT_POPUP = false;
+ }
+ bus.connect().subscribe(AppLifecycleListener.TOPIC, new AppLifecycleListener.Adapter() {
+ @Override
+ public void appFrameCreated(String[] commandLineArgs, @NotNull Ref<Boolean> willOpenProject) {
+ if (!propertiesComponent.isValueSet(DISPLAYED_PROPERTY)) {
+ GeneralSettings.getInstance().setShowTipsOnStartup(false);
+ showInitialConfigurationDialog();
+ propertiesComponent.setValue(DISPLAYED_PROPERTY, "true");
+ }
+ }
+
+ @Override
+ public void appStarting(Project projectFromCommandLine) {
+ patchKeymap();
+ }
+ });
+ bus.connect().subscribe(ProjectManager.TOPIC, new ProjectManagerAdapter() {
+ @Override
+ public void projectOpened(final Project project) {
+ if (project.isDefault()) return;
+ if (FileChooserUtil.getLastOpenedFile(project) == null) {
+ FileChooserUtil.setLastOpenedFile(project, VfsUtil.getUserHomeDir());
+ }
+
+ patchProjectAreaExtensions(project);
+
+ //StartupManager.getInstance(project).runWhenProjectIsInitialized(new DumbAwareRunnable() {
+ // @Override
+ // public void run() {
+ // if (project.isDisposed()) return;
+ //
+ // ToolWindowManager.getInstance(project).invokeLater(new Runnable() {
+ // int count = 0;
+ // public void run() {
+ // if (project.isDisposed()) return;
+ // if (count ++ < 3) {
+ // ToolWindowManager.getInstance(project).invokeLater(this);
+ // return;
+ // }
+ // if (!propertiesComponent.isValueSet(INIT_DB_DIALOG_DISPLAYED)) {
+ // ToolWindow toolWindow = DatabaseView.getDatabaseToolWindow(project);
+ // if (toolWindow.getType() != ToolWindowType.SLIDING) {
+ // toolWindow.activate(null);
+ // }
+ // propertiesComponent.setValue(INIT_DB_DIALOG_DISPLAYED, "true");
+ // onFirstProjectOpened(project);
+ // }
+ // }
+ // });
+ // }
+ //});
+ }
+ });
+ }
+
+ private static void onFirstProjectOpened(@NotNull final Project project) {
+ // show python console
+
+
+ GeneralSettings.getInstance().setShowTipsOnStartup(true);
+
+ // show tips once
+ final Alarm alarm = new Alarm(project);
+ alarm.addRequest(new Runnable() {
+ @Override
+ public void run() {
+ Disposer.dispose(alarm);
+ TipDialog.createForProject(project).show();
+ }
+ }, 2000, ModalityState.NON_MODAL);
+ }
+
+ private static void patchRootAreaExtensions() {
+ ExtensionsArea rootArea = Extensions.getArea(null);
+
+ for (ToolWindowEP ep : Extensions.getExtensions(ToolWindowEP.EP_NAME)) {
+ if (ToolWindowId.FAVORITES_VIEW.equals(ep.id) || ToolWindowId.TODO_VIEW.equals(ep.id) || EventLog.LOG_TOOL_WINDOW_ID.equals(ep.id)) {
+ rootArea.getExtensionPoint(ToolWindowEP.EP_NAME).unregisterExtension(ep);
+ }
+ }
+
+ for (DirectoryProjectConfigurator ep : Extensions.getExtensions(DirectoryProjectConfigurator.EP_NAME)) {
+ if (ep instanceof PlatformProjectViewOpener) {
+ rootArea.getExtensionPoint(DirectoryProjectConfigurator.EP_NAME).unregisterExtension(ep);
+ }
+ }
+
+ for (IntentionActionBean ep : Extensions.getExtensions(IntentionManager.EP_INTENTION_ACTIONS)) {
+ if ("org.intellij.lang.regexp.intention.CheckRegExpIntentionAction".equals(ep.className)) {
+ rootArea.getExtensionPoint(IntentionManager.EP_INTENTION_ACTIONS).unregisterExtension(ep);
+ }
+ }
+ }
+
+ private static void patchProjectAreaExtensions(@NotNull final Project project) {
+ for (SelectInTarget target : Extensions.getExtensions(SelectInTarget.EP_NAME, project)) {
+ if (ToolWindowId.FAVORITES_VIEW.equals(target.getToolWindowId())) {
+ Extensions.getArea(project).getExtensionPoint(SelectInTarget.EP_NAME).unregisterExtension(target);
+ }
+ }
+ }
+
+ private static void patchKeymap() {
+ Set<String> droppedActions = ContainerUtil.newHashSet(
+ "AddToFavoritesPopup", "RemoveFromFavorites",
+ "DatabaseView.ImportDataSources",
+ "CompileDirty", "Compile",
+ // hidden
+ "AddNewFavoritesList", "EditFavorites", "RemoveFromFavorites", "RenameFavoritesList", "RemoveFavoritesList");
+ KeymapManagerEx keymapManager = KeymapManagerEx.getInstanceEx();
+
+
+ for (Keymap keymap : keymapManager.getAllKeymaps()) {
+ if (keymap.canModify()) continue;
+
+ KeymapImpl keymapImpl = (KeymapImpl)keymap;
+
+ for (String id : keymapImpl.getOwnActionIds()) {
+ if (droppedActions.contains(id)) keymapImpl.clearOwnActionsId(id);
+ }
+ }
+ }
+
+ private static void showInitialConfigurationDialog() {
+ final JFrame frame = WindowManager.getInstance().findVisibleFrame();
+ new InitialConfigurationDialog(frame, "Python").show();
+ }
+}