a248fb2eefee31bc1d12ef187689217226014ce8
[idea/community.git] / python / ide / src / com / jetbrains / python / newProject / actions / PyCharmNewProjectStep.java
1 /*
2  * Copyright 2000-2014 JetBrains s.r.o.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.jetbrains.python.newProject.actions;
17
18 import com.google.common.collect.Lists;
19 import com.intellij.ide.util.projectWizard.AbstractNewProjectStep;
20 import com.intellij.ide.util.projectWizard.ProjectSettingsStepBase;
21 import com.intellij.ide.util.projectWizard.actions.ProjectSpecificAction;
22 import com.intellij.openapi.actionSystem.AnAction;
23 import com.intellij.openapi.ui.Messages;
24 import com.intellij.platform.DirectoryProjectGenerator;
25 import com.intellij.util.BooleanFunction;
26 import com.intellij.util.NullableConsumer;
27 import com.jetbrains.python.newProject.PyFrameworkProjectGenerator;
28 import com.jetbrains.python.newProject.PythonBaseProjectGenerator;
29 import com.jetbrains.python.newProject.PythonProjectGenerator;
30 import org.jetbrains.annotations.NotNull;
31 import org.jetbrains.annotations.Nullable;
32
33 import java.util.Arrays;
34 import java.util.Comparator;
35 import java.util.List;
36
37 public class PyCharmNewProjectStep extends AbstractNewProjectStep {
38
39   public PyCharmNewProjectStep() {
40     super(new Customization());
41   }
42
43   private static class Customization extends AbstractNewProjectStep.Customization {
44     private final List<DirectoryProjectGenerator> pluginSpecificGenerators = Lists.newArrayList();
45
46     @NotNull
47     @Override
48     protected NullableConsumer<ProjectSettingsStepBase> createCallback() {
49       return new GenerateProjectCallback();
50     }
51
52     @NotNull
53     @Override
54     protected DirectoryProjectGenerator createEmptyProjectGenerator() {
55       return new PythonBaseProjectGenerator();
56     }
57
58     @NotNull
59     @Override
60     protected ProjectSettingsStepBase createProjectSpecificSettingsStep(@NotNull DirectoryProjectGenerator emptyProjectGenerator,
61                                                                         @NotNull NullableConsumer<ProjectSettingsStepBase> callback) {
62       return new ProjectSpecificSettingsStep(emptyProjectGenerator, callback);
63     }
64
65     @NotNull
66     @Override
67     protected DirectoryProjectGenerator[] getProjectGenerators() {
68       DirectoryProjectGenerator[] generators = super.getProjectGenerators();
69
70       Arrays.sort(generators, (o1, o2) -> {
71         if (o1 instanceof PyFrameworkProjectGenerator && !(o2 instanceof PyFrameworkProjectGenerator)) return -1;
72         if (!(o1 instanceof PyFrameworkProjectGenerator) && o2 instanceof PyFrameworkProjectGenerator) return 1;
73         return o1.getName().compareTo(o2.getName());
74       });
75       return generators;
76     }
77
78     @Override
79     public void setUpBasicAction(@NotNull ProjectSpecificAction projectSpecificAction, @NotNull DirectoryProjectGenerator[] generators) {
80       if (generators.length == 0) {
81         projectSpecificAction.setPopup(false);
82       }
83     }
84
85     @NotNull
86     @Override
87     public AnAction[] getActions(@NotNull DirectoryProjectGenerator generator, @NotNull NullableConsumer<ProjectSettingsStepBase> callback) {
88       if (generator instanceof PythonProjectGenerator) {
89         ProjectSpecificAction group =
90           new ProjectSpecificAction(generator, new ProjectSpecificSettingsStep(generator, new PythonGenerateProjectCallback()));
91         return group.getChildren(null);
92       }
93       else {
94         pluginSpecificGenerators.add(generator);
95         return AnAction.EMPTY_ARRAY;
96       }
97     }
98
99     @NotNull
100     @Override
101     public AnAction[] getExtraActions(@NotNull NullableConsumer<ProjectSettingsStepBase> callback) {
102       if (!pluginSpecificGenerators.isEmpty()) {
103         PluginSpecificProjectsStep step = new PluginSpecificProjectsStep(callback, pluginSpecificGenerators);
104         return step.getChildren(null);
105       }
106       return AnAction.EMPTY_ARRAY;
107     }
108   }
109
110   private static class PythonGenerateProjectCallback implements NullableConsumer<ProjectSettingsStepBase> {
111     @Override
112     public void consume(@Nullable ProjectSettingsStepBase base) {
113       if (base == null) return;
114       final DirectoryProjectGenerator generator = base.getProjectGenerator();
115       final NullableConsumer<ProjectSettingsStepBase> callback = new GenerateProjectCallback();
116       if (generator instanceof PythonProjectGenerator && base instanceof ProjectSpecificSettingsStep) {
117         final BooleanFunction<PythonProjectGenerator> beforeProjectGenerated = ((PythonProjectGenerator)generator).
118           beforeProjectGenerated(((ProjectSpecificSettingsStep)base).getSdk());
119         if (beforeProjectGenerated != null) {
120           final boolean result = beforeProjectGenerated.fun((PythonProjectGenerator)generator);
121           if (result) {
122             callback.consume(base);
123           }
124           else {
125             Messages.showWarningDialog("Project can not be generated", "Error in Project Generation");
126           }
127         }
128         else {
129           callback.consume(base);
130         }
131       }
132     }
133   }
134 }