added "Learn Python" action to the Welcome screen
authorEkaterina Tuzova <Ekaterina.Tuzova@jetbrains.com>
Tue, 19 Aug 2014 14:59:08 +0000 (18:59 +0400)
committerEkaterina Tuzova <Ekaterina.Tuzova@jetbrains.com>
Tue, 19 Aug 2014 14:59:08 +0000 (18:59 +0400)
python/edu/learn-python/learn-python.iml
python/edu/learn-python/resources/META-INF/plugin.xml
python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyNewProject.java [new file with mode: 0644]
python/ide/src/com/jetbrains/python/newProject/actions/GenerateProjectCallback.java [new file with mode: 0644]
python/ide/src/com/jetbrains/python/newProject/actions/ProjectSpecificAction.java
python/ide/src/com/jetbrains/python/newProject/actions/PyCharmNewProjectStep.java

index bd539d1e21472393fe0b480a0dce59d7784afa0c..613d67594a7a46e7c669f54c6db62e23c88caae7 100644 (file)
@@ -15,6 +15,7 @@
     <orderEntry type="module" module-name="lang-impl" />
     <orderEntry type="library" name="gson" level="project" />
     <orderEntry type="library" name="JUnit4" level="project" />
     <orderEntry type="module" module-name="lang-impl" />
     <orderEntry type="library" name="gson" level="project" />
     <orderEntry type="library" name="JUnit4" level="project" />
+    <orderEntry type="module" module-name="python-ide-community" />
   </component>
 </module>
 
   </component>
 </module>
 
index be379436157fe187e8f012c6e2a02e9b7fea2806..ed59420570baf951f9dc3ac5998faa2471341429 100644 (file)
             description="show hint">
       <add-to-group group-id="MainToolBar" anchor="last"/>
     </action>
             description="show hint">
       <add-to-group group-id="MainToolBar" anchor="last"/>
     </action>
+
+    <action id="WelcomeScreen.LearnPython" class="com.jetbrains.python.edu.actions.StudyNewProject" icon="StudyIcons.EducationalProjectType">
+      <add-to-group group-id="WelcomeScreen.QuickStart" anchor="first"/>
+    </action>
+
   </actions>
 
   <extensions defaultExtensionNs="com.intellij">
   </actions>
 
   <extensions defaultExtensionNs="com.intellij">
diff --git a/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyNewProject.java b/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyNewProject.java
new file mode 100644 (file)
index 0000000..665cfd7
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * 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.actions;
+
+import com.jetbrains.python.edu.StudyDirectoryProjectGenerator;
+import com.jetbrains.python.newProject.actions.GenerateProjectCallback;
+import com.jetbrains.python.newProject.actions.ProjectSpecificAction;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+public class StudyNewProject extends ProjectSpecificAction {
+
+  public StudyNewProject(@NotNull final String name, @Nullable final Runnable runnable) {
+    super(new GenerateProjectCallback(runnable), new StudyDirectoryProjectGenerator(), name);
+  }
+
+  public StudyNewProject() {
+    this("Learn Python", null);
+  }
+
+}
diff --git a/python/ide/src/com/jetbrains/python/newProject/actions/GenerateProjectCallback.java b/python/ide/src/com/jetbrains/python/newProject/actions/GenerateProjectCallback.java
new file mode 100644 (file)
index 0000000..2aa9a39
--- /dev/null
@@ -0,0 +1,159 @@
+/*
+ * 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.newProject.actions;
+
+import com.intellij.ide.GeneralSettings;
+import com.intellij.ide.util.projectWizard.WebProjectTemplate;
+import com.intellij.internal.statistic.UsageTrigger;
+import com.intellij.internal.statistic.beans.ConvertUsagesUtil;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.options.ConfigurationException;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.project.ProjectManager;
+import com.intellij.openapi.projectRoots.ProjectJdkTable;
+import com.intellij.openapi.projectRoots.Sdk;
+import com.intellij.openapi.projectRoots.SdkAdditionalData;
+import com.intellij.openapi.projectRoots.impl.SdkConfigurationUtil;
+import com.intellij.openapi.roots.ui.configuration.projectRoot.ProjectSdksModel;
+import com.intellij.openapi.ui.Messages;
+import com.intellij.openapi.util.Computable;
+import com.intellij.openapi.vfs.LocalFileSystem;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.platform.DirectoryProjectGenerator;
+import com.intellij.platform.PlatformProjectOpenProcessor;
+import com.intellij.projectImport.ProjectOpenedCallback;
+import com.intellij.util.NullableConsumer;
+import com.jetbrains.python.configuration.PyConfigurableInterpreterList;
+import com.jetbrains.python.newProject.PyNewProjectSettings;
+import com.jetbrains.python.newProject.PythonProjectGenerator;
+import com.jetbrains.python.sdk.PyDetectedSdk;
+import com.jetbrains.python.sdk.PySdkService;
+import com.jetbrains.python.sdk.PythonSdkAdditionalData;
+import com.jetbrains.python.sdk.PythonSdkType;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.File;
+import java.util.List;
+
+public class GenerateProjectCallback implements NullableConsumer<AbstractProjectSettingsStep> {
+  private static final Logger LOG = Logger.getInstance(GenerateProjectCallback.class);
+  @Nullable private final Runnable myRunnable;
+
+  public GenerateProjectCallback(@Nullable final Runnable runnable) {
+
+    myRunnable = runnable;
+  }
+
+  @Override
+  public void consume(@Nullable AbstractProjectSettingsStep settingsStep) {
+    if (myRunnable != null) {
+      myRunnable.run();
+    }
+    if (settingsStep == null) return;
+
+    Sdk sdk = settingsStep.getSdk();
+    final Project project = ProjectManager.getInstance().getDefaultProject();
+    final ProjectSdksModel model = PyConfigurableInterpreterList.getInstance(project).getModel();
+    if (sdk instanceof PyDetectedSdk) {
+      final String name = sdk.getName();
+      VirtualFile sdkHome = ApplicationManager.getApplication().runWriteAction(new Computable<VirtualFile>() {
+        @Override
+        public VirtualFile compute() {
+          return LocalFileSystem.getInstance().refreshAndFindFileByPath(name);
+        }
+      });
+      PySdkService.getInstance().solidifySdk(sdk);
+      sdk = SdkConfigurationUtil.setupSdk(ProjectJdkTable.getInstance().getAllJdks(), sdkHome, PythonSdkType.getInstance(), true, null,
+                                          null);
+      model.addSdk(sdk);
+      settingsStep.setSdk(sdk);
+      try {
+        model.apply();
+      }
+      catch (ConfigurationException exception) {
+        LOG.error("Error adding detected python interpreter " + exception.getMessage());
+      }
+    }
+    Project newProject = generateProject(project, settingsStep);
+    if (newProject != null) {
+      SdkConfigurationUtil.setDirectoryProjectSdk(newProject, sdk);
+      final List<Sdk> sdks = PythonSdkType.getAllSdks();
+      for (Sdk s : sdks) {
+        final SdkAdditionalData additionalData = s.getSdkAdditionalData();
+        if (additionalData instanceof PythonSdkAdditionalData) {
+          ((PythonSdkAdditionalData)additionalData).reassociateWithCreatedProject(newProject);
+        }
+      }
+    }
+  }
+
+  @Nullable
+  private Project generateProject(@NotNull final Project project, @NotNull final AbstractProjectSettingsStep settings) {
+    final DirectoryProjectGenerator generator = settings.getProjectGenerator();
+    final File location = new File(settings.getProjectLocation());
+    if (!location.exists() && !location.mkdirs()) {
+      Messages.showErrorDialog(project, "Cannot create directory '" + location + "'", "Create Project");
+      return null;
+    }
+
+    final VirtualFile baseDir = ApplicationManager.getApplication().runWriteAction(new Computable<VirtualFile>() {
+      public VirtualFile compute() {
+        return LocalFileSystem.getInstance().refreshAndFindFileByIoFile(location);
+      }
+    });
+    LOG.assertTrue(baseDir != null, "Couldn't find '" + location + "' in VFS");
+    baseDir.refresh(false, true);
+
+    if (baseDir.getChildren().length > 0) {
+      int rc = Messages.showYesNoDialog(project,
+                                        "The directory '" + location +
+                                        "' is not empty. Would you like to create a project from existing sources instead?",
+                                        "Create New Project", Messages.getQuestionIcon());
+      if (rc == Messages.YES) {
+        return PlatformProjectOpenProcessor.getInstance().doOpenProject(baseDir, null, false);
+      }
+    }
+
+    String generatorName = generator == null ? "empty" : ConvertUsagesUtil.ensureProperKey(generator.getName());
+    UsageTrigger.trigger("NewDirectoryProjectAction." + generatorName);
+
+    GeneralSettings.getInstance().setLastProjectCreationLocation(location.getParent());
+
+    return PlatformProjectOpenProcessor.doOpenProject(baseDir, null, false, -1, new ProjectOpenedCallback() {
+      @Override
+      public void projectOpened(Project project, Module module) {
+        if (generator != null) {
+          Object projectSettings = null;
+          if (generator instanceof PythonProjectGenerator) {
+            projectSettings = ((PythonProjectGenerator)generator).getProjectSettings();
+          }
+          else if (generator instanceof WebProjectTemplate) {
+            projectSettings = ((WebProjectTemplate)generator).getPeer().getSettings();
+          }
+          if (projectSettings instanceof PyNewProjectSettings) {
+            ((PyNewProjectSettings)projectSettings).setSdk(settings.getSdk());
+            ((PyNewProjectSettings)projectSettings).setInstallFramework(settings.installFramework());
+          }
+          //noinspection unchecked
+          generator.generateProject(project, baseDir, projectSettings, module);
+        }
+      }
+    }, false);
+  }
+}
index 4397a090b253dd17e1a7df3d24497a61cdacab00..85cf6d118d34d9f58b23ab49ef7576a6a1a91916 100644 (file)
@@ -29,7 +29,13 @@ public class ProjectSpecificAction extends DefaultActionGroup implements DumbAwa
 
   public ProjectSpecificAction(@NotNull final NullableConsumer<AbstractProjectSettingsStep> callback,
                                @NotNull final DirectoryProjectGenerator projectGenerator) {
 
   public ProjectSpecificAction(@NotNull final NullableConsumer<AbstractProjectSettingsStep> callback,
                                @NotNull final DirectoryProjectGenerator projectGenerator) {
-    super(projectGenerator.getName(), true);
+    this(callback, projectGenerator, projectGenerator.getName());
+  }
+
+  public ProjectSpecificAction(@NotNull final NullableConsumer<AbstractProjectSettingsStep> callback,
+                               @NotNull final DirectoryProjectGenerator projectGenerator,
+                               @NotNull final String name) {
+    super(name, true);
     getTemplatePresentation().setIcon(projectGenerator.getLogo());
     mySettings = new ProjectSpecificSettingsStep(projectGenerator, callback);
     add(mySettings);
     getTemplatePresentation().setIcon(projectGenerator.getLogo());
     mySettings = new ProjectSpecificSettingsStep(projectGenerator, callback);
     add(mySettings);
index 4f9f1074df68e32c14bd695f9e4adc080d42bba8..b15c20606dedc2e61e46752da243a91b4e2ffcaf 100644 (file)
 package com.jetbrains.python.newProject.actions;
 
 import com.google.common.collect.Lists;
 package com.jetbrains.python.newProject.actions;
 
 import com.google.common.collect.Lists;
-import com.intellij.ide.GeneralSettings;
-import com.intellij.ide.util.projectWizard.WebProjectTemplate;
-import com.intellij.internal.statistic.UsageTrigger;
-import com.intellij.internal.statistic.beans.ConvertUsagesUtil;
 import com.intellij.openapi.actionSystem.DefaultActionGroup;
 import com.intellij.openapi.actionSystem.DefaultActionGroup;
-import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.extensions.Extensions;
 import com.intellij.openapi.extensions.Extensions;
-import com.intellij.openapi.module.Module;
-import com.intellij.openapi.options.ConfigurationException;
 import com.intellij.openapi.project.DumbAware;
 import com.intellij.openapi.project.DumbAware;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.project.ProjectManager;
-import com.intellij.openapi.projectRoots.ProjectJdkTable;
-import com.intellij.openapi.projectRoots.Sdk;
-import com.intellij.openapi.projectRoots.SdkAdditionalData;
-import com.intellij.openapi.projectRoots.impl.SdkConfigurationUtil;
-import com.intellij.openapi.roots.ui.configuration.projectRoot.ProjectSdksModel;
-import com.intellij.openapi.ui.Messages;
-import com.intellij.openapi.util.Computable;
-import com.intellij.openapi.vfs.LocalFileSystem;
-import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.platform.DirectoryProjectGenerator;
 import com.intellij.platform.DirectoryProjectGenerator;
-import com.intellij.platform.PlatformProjectOpenProcessor;
-import com.intellij.projectImport.ProjectOpenedCallback;
 import com.intellij.util.NullableConsumer;
 import com.intellij.util.NullableConsumer;
-import com.jetbrains.python.configuration.PyConfigurableInterpreterList;
 import com.jetbrains.python.newProject.PyFrameworkProjectGenerator;
 import com.jetbrains.python.newProject.PyFrameworkProjectGenerator;
-import com.jetbrains.python.newProject.PyNewProjectSettings;
 import com.jetbrains.python.newProject.PythonBaseProjectGenerator;
 import com.jetbrains.python.newProject.PythonProjectGenerator;
 import com.jetbrains.python.newProject.PythonBaseProjectGenerator;
 import com.jetbrains.python.newProject.PythonProjectGenerator;
-import com.jetbrains.python.sdk.PyDetectedSdk;
-import com.jetbrains.python.sdk.PySdkService;
-import com.jetbrains.python.sdk.PythonSdkAdditionalData;
-import com.jetbrains.python.sdk.PythonSdkType;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
-import java.io.File;
 import java.util.Arrays;
 import java.util.Comparator;
 import java.util.List;
 
 public class PyCharmNewProjectStep extends DefaultActionGroup implements DumbAware {
 import java.util.Arrays;
 import java.util.Comparator;
 import java.util.List;
 
 public class PyCharmNewProjectStep extends DefaultActionGroup implements DumbAware {
-  private static final Logger LOG = Logger.getInstance(PyCharmNewProjectStep.class);
 
   public PyCharmNewProjectStep(@NotNull final String name, @Nullable final Runnable runnable) {
     super(name, true);
 
 
   public PyCharmNewProjectStep(@NotNull final String name, @Nullable final Runnable runnable) {
     super(name, true);
 
-    final NullableConsumer<AbstractProjectSettingsStep> callback = new NullableConsumer<AbstractProjectSettingsStep>() {
-      @Override
-      public void consume(@Nullable AbstractProjectSettingsStep settingsStep) {
-        if (runnable != null)
-          runnable.run();
-        if (settingsStep == null) return;
-
-        Sdk sdk = settingsStep.getSdk();
-        final Project project = ProjectManager.getInstance().getDefaultProject();
-        final ProjectSdksModel model = PyConfigurableInterpreterList.getInstance(project).getModel();
-        if (sdk instanceof PyDetectedSdk) {
-          final String name = sdk.getName();
-          VirtualFile sdkHome = ApplicationManager.getApplication().runWriteAction(new Computable<VirtualFile>() {
-            @Override
-            public VirtualFile compute() {
-              return LocalFileSystem.getInstance().refreshAndFindFileByPath(name);
-            }
-          });
-          PySdkService.getInstance().solidifySdk(sdk);
-          sdk = SdkConfigurationUtil.setupSdk(ProjectJdkTable.getInstance().getAllJdks(), sdkHome, PythonSdkType.getInstance(), true, null,
-                                              null);
-          model.addSdk(sdk);
-          settingsStep.setSdk(sdk);
-          try {
-            model.apply();
-          }
-          catch (ConfigurationException exception) {
-            LOG.error("Error adding detected python interpreter " + exception.getMessage());
-          }
-        }
-        Project newProject = generateProject(project, settingsStep);
-        if (newProject != null) {
-          SdkConfigurationUtil.setDirectoryProjectSdk(newProject, sdk);
-          final List<Sdk> sdks = PythonSdkType.getAllSdks();
-          for (Sdk s : sdks) {
-            final SdkAdditionalData additionalData = s.getSdkAdditionalData();
-            if (additionalData instanceof PythonSdkAdditionalData) {
-              ((PythonSdkAdditionalData)additionalData).reassociateWithCreatedProject(newProject);
-            }
-          }
-        }
-      }
-
-      @Nullable
-      private Project generateProject(@NotNull final Project project, @NotNull final AbstractProjectSettingsStep settings) {
-        final DirectoryProjectGenerator generator = settings.getProjectGenerator();
-        final File location = new File(settings.getProjectLocation());
-        if (!location.exists() && !location.mkdirs()) {
-          Messages.showErrorDialog(project, "Cannot create directory '" + location + "'", "Create Project");
-          return null;
-        }
-
-        final VirtualFile baseDir = ApplicationManager.getApplication().runWriteAction(new Computable<VirtualFile>() {
-          public VirtualFile compute() {
-            return LocalFileSystem.getInstance().refreshAndFindFileByIoFile(location);
-          }
-        });
-        LOG.assertTrue(baseDir != null, "Couldn't find '" + location + "' in VFS");
-        baseDir.refresh(false, true);
-
-        if (baseDir.getChildren().length > 0) {
-          int rc = Messages.showYesNoDialog(project,
-                                            "The directory '" + location +
-                                            "' is not empty. Would you like to create a project from existing sources instead?",
-                                            "Create New Project", Messages.getQuestionIcon());
-          if (rc == Messages.YES) {
-            return PlatformProjectOpenProcessor.getInstance().doOpenProject(baseDir, null, false);
-          }
-        }
-
-        String generatorName = generator == null ? "empty" : ConvertUsagesUtil.ensureProperKey(generator.getName());
-        UsageTrigger.trigger("NewDirectoryProjectAction." + generatorName);
-
-        GeneralSettings.getInstance().setLastProjectCreationLocation(location.getParent());
-
-        return PlatformProjectOpenProcessor.doOpenProject(baseDir, null, false, -1, new ProjectOpenedCallback() {
-          @Override
-          public void projectOpened(Project project, Module module) {
-            if (generator != null) {
-              Object projectSettings = null;
-              if (generator instanceof PythonProjectGenerator)
-                projectSettings = ((PythonProjectGenerator)generator).getProjectSettings();
-              else if (generator instanceof WebProjectTemplate) {
-                projectSettings = ((WebProjectTemplate)generator).getPeer().getSettings();
-              }
-              if (projectSettings instanceof PyNewProjectSettings) {
-                ((PyNewProjectSettings)projectSettings).setSdk(settings.getSdk());
-                ((PyNewProjectSettings)projectSettings).setInstallFramework(settings.installFramework());
-              }
-              //noinspection unchecked
-              generator.generateProject(project, baseDir, projectSettings, module);
-            }
-          }
-        }, false);
-      }
-    };
+    final NullableConsumer<AbstractProjectSettingsStep> callback = new GenerateProjectCallback(runnable);
 
     final ProjectSpecificAction action = new ProjectSpecificAction(callback, new PythonBaseProjectGenerator());
     add(action);
 
     final ProjectSpecificAction action = new ProjectSpecificAction(callback, new PythonBaseProjectGenerator());
     add(action);